ROOT  6.06/09
Reference Guide
TGX11TTF.cxx
Go to the documentation of this file.
1 // @(#)root/x11ttf:$Id: 80028b538e60290371c1c5d73728f78b1c32f09a $
2 // Author: Valeriy Onuchin (Xft support) 02/10/07
3 // Author: Olivier Couet 01/10/02
4 // Author: Fons Rademakers 21/11/98
5 
6 /*************************************************************************
7  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
8  * All rights reserved. *
9  * *
10  * For the licensing terms see $ROOTSYS/LICENSE. *
11  * For the list of contributors see $ROOTSYS/README/CREDITS. *
12  *************************************************************************/
13 
14 /** \class TGX11TTF
15 \ingroup x11
16 
17 Interface to low level X11 (Xlib). This class gives access to basic
18 X11 graphics via the parent class TGX11. However, all text and font
19 handling is done via the Freetype TrueType library. When the
20 shared library containing this class is loaded the global gVirtualX
21 is redirected to point to this class.
22 */
23 
24 #include <stdlib.h>
25 
26 # include <ft2build.h>
27 # include FT_FREETYPE_H
28 # include FT_GLYPH_H
29 #include "TGX11TTF.h"
30 #include "TClass.h"
31 #include "TEnv.h"
32 
33 #include <X11/Xlib.h>
34 #include <X11/Xutil.h>
35 #include <X11/Xatom.h>
36 #include <X11/cursorfont.h>
37 #include <X11/keysym.h>
38 #include <X11/xpm.h>
39 
40 struct RXColor:XColor{};
41 struct RVisual:Visual{};
42 struct RXImage:XImage{};
43 
44 #ifdef R__HAS_XFT
45 
46 #include "THashTable.h"
47 #include "TRefCnt.h"
48 #include <X11/Xft/Xft.h>
49 
50 ///////////////////////// xft font data //////////////////////////////////////
51 class TXftFontData : public TNamed, public TRefCnt {
52 public:
53  GContext_t fGC; // graphics context
54  XftFont *fXftFont; // xft font
55 
56  TXftFontData(GContext_t gc, XftFont *xftfont, const char *name) :
57  TNamed(name, ""), TRefCnt(), fXftFont(xftfont)
58  {
59  SetRefCount(1);
60  fGC = gc;
61  }
62 
63  void MapGCFont(GContext_t gc, FontStruct_t font)
64  {
65  fGC = gc; fXftFont = (XftFont *)font;
66  }
67 
68  ~TXftFontData()
69  {
70  if (fXftFont) XftFontClose((Display*)gVirtualX->GetDisplay(), fXftFont);
71  }
72 };
73 
74 /////////////////// hash table //////////////////////////////////////////////
75 class TXftFontHash {
76 public:
77  THashTable *fList; // hash table
78 
79  TXftFontHash() { fList = new THashTable(50); }
80 
81  TXftFontData *FindByName(const char *name)
82  {
83  return (TXftFontData*)fList->FindObject(name);
84  }
85 
86  TXftFontData *FindByFont(FontStruct_t font)
87  {
88  TIter next(fList);
89  TXftFontData *d = 0;
90 
91  while ((d = (TXftFontData*) next())) {
92  if (d->fXftFont == (XftFont *)font) {
93  return d;
94  }
95  }
96  return 0;
97  }
98 
99  TXftFontData *FindByGC(GContext_t gc)
100  {
101  TIter next(fList);
102  TXftFontData *d = 0;
103 
104  while ((d = (TXftFontData*) next())) {
105  if (d->fGC == gc) {
106  return d;
107  }
108  }
109  return 0;
110  }
111 
112  void AddFont(TXftFontData *data)
113  {
114  fList->Add(data);
115  }
116 
117  void FreeFont(TXftFontData *data)
118  {
119  if (data->RemoveReference() > 0) return;
120  fList->Remove(data);
121  delete data;
122  }
123 };
124 #endif // R__HAS_XFT
125 
126 /** \class TTFX11Init
127 \ingroup GraphicsBackends
128 
129 Small utility class that takes care of switching the current
130 gVirtualX to the new TGX11TTF class as soon as the shared library
131 containing this class is loaded.
132 */
133 
134 class TTFX11Init {
135 public:
136  TTFX11Init() { TGX11TTF::Activate(); }
137 };
138 static TTFX11Init gTTFX11Init;
139 
140 
142 
143 ////////////////////////////////////////////////////////////////////////////////
144 /// Create copy of TGX11 but now use TrueType fonts.
145 
146 TGX11TTF::TGX11TTF(const TGX11 &org) : TGX11(org)
147 {
148  SetName("X11TTF");
149  SetTitle("ROOT interface to X11 with TrueType fonts");
150 
151  if (!TTF::fgInit) TTF::Init();
152 
153  fHasTTFonts = kTRUE;
154  fHasXft = kFALSE;
155  fAlign.x = 0;
156  fAlign.y = 0;
157 
158 #ifdef R__HAS_XFT
159  fXftFontHash = 0;
160 #endif
161 }
162 
163 ////////////////////////////////////////////////////////////////////////////////
164 /// Static method setting TGX11TTF as the acting gVirtualX.
165 
167 {
168  if (gVirtualX && dynamic_cast<TGX11*>(gVirtualX)) {
169  TGX11 *oldg = (TGX11 *) gVirtualX;
170  gVirtualX = new TGX11TTF(*oldg);
171  delete oldg;
172  }
173 }
174 
175 ////////////////////////////////////////////////////////////////////////////////
176 /// Initialize X11 system. Returns kFALSE in case of failure.
177 
178 Bool_t TGX11TTF::Init(void *display)
179 {
180 #ifdef R__HAS_XFT
181  fXftFontHash = 0;
182  XFontStruct *fs = 0;
183  if (display) fs = XLoadQueryFont((Display *)display, "-*-helvetica-*-r-*-*-14-*-*-*-*-*-*-*");
184  if (!fs) gEnv->SetValue("X11.UseXft", 1);
185  if (display && fs) XFreeFont((Display *)display, fs);
186  if (gEnv->GetValue("X11.UseXft", 0)) {
187  fHasXft = kTRUE;
188  fXftFontHash = new TXftFontHash();
189  }
190 #endif
191  Bool_t r = TGX11::Init(display);
192 
193  if (fDepth > 8) {
195  } else {
197  }
198 
199  return r;
200 }
201 
202 ////////////////////////////////////////////////////////////////////////////////
203 /// Compute alignment variables. The alignment is done on the horizontal string
204 /// then the rotation is applied on the alignment variables.
205 /// SetRotation and LayoutGlyphs should have been called before.
206 
207 void TGX11TTF::Align(void)
208 {
209  EAlign align = (EAlign) fTextAlign;
210 
211  // vertical alignment
212  if (align == kTLeft || align == kTCenter || align == kTRight) {
213  fAlign.y = TTF::fgAscent;
214  } else if (align == kMLeft || align == kMCenter || align == kMRight) {
215  fAlign.y = TTF::fgAscent/2;
216  } else {
217  fAlign.y = 0;
218  }
219 
220  // horizontal alignment
221  if (align == kTRight || align == kMRight || align == kBRight) {
222  fAlign.x = TTF::fgWidth;
223  } else if (align == kTCenter || align == kMCenter || align == kBCenter) {
224  fAlign.x = TTF::fgWidth/2;
225  } else {
226  fAlign.x = 0;
227  }
228 
229  FT_Vector_Transform(&fAlign, TTF::fgRotMatrix);
230  fAlign.x = fAlign.x >> 6;
231  fAlign.y = fAlign.y >> 6;
232 }
233 
234 ////////////////////////////////////////////////////////////////////////////////
235 /// Draw FT_Bitmap bitmap to xim image at position bx,by using specified
236 /// foreground color.
237 
238 void TGX11TTF::DrawImage(FT_Bitmap *source, ULong_t fore, ULong_t back,
239  RXImage *xim, Int_t bx, Int_t by)
240 {
241  UChar_t d = 0, *s = source->buffer;
242 
243  if (TTF::fgSmoothing) {
244 
245  static RXColor col[5];
246  RXColor *bcol = 0;
247  XColor *bc;
248  Int_t x, y;
249 
250  // background kClear, i.e. transparent, we take as background color
251  // the average of the rgb values of all pixels covered by this character
252  if (back == (ULong_t) -1 && (UInt_t)source->width) {
253  ULong_t r, g, b;
254  Int_t dots, dotcnt;
255  const Int_t maxdots = 50000;
256 
257  dots = Int_t(source->width * source->rows);
258  dots = dots > maxdots ? maxdots : dots;
259  bcol = new RXColor[dots];
260  if (!bcol) return;
261  bc = bcol;
262  dotcnt = 0;
263  for (y = 0; y < (int) source->rows; y++) {
264  for (x = 0; x < (int) source->width; x++, bc++) {
265 /// bc->pixel = XGetPixel(xim, bx + x, by - c->TTF::fgAscent + y);
266  bc->pixel = XGetPixel(xim, bx + x, by + y);
267  bc->flags = DoRed | DoGreen | DoBlue;
268  if (++dotcnt >= maxdots) break;
269  }
270  }
271  QueryColors(fColormap, bcol, dots);
272  r = g = b = 0;
273  bc = bcol;
274  dotcnt = 0;
275  for (y = 0; y < (int) source->rows; y++) {
276  for (x = 0; x < (int) source->width; x++, bc++) {
277  r += bc->red;
278  g += bc->green;
279  b += bc->blue;
280  if (++dotcnt >= maxdots) break;
281  }
282  }
283  if (dots != 0) {
284  r /= dots;
285  g /= dots;
286  b /= dots;
287  }
288  bc = &col[0];
289  if (bc->red == r && bc->green == g && bc->blue == b)
290  bc->pixel = back;
291  else {
292  bc->pixel = ~back;
293  bc->red = (UShort_t) r;
294  bc->green = (UShort_t) g;
295  bc->blue = (UShort_t) b;
296  }
297  }
298  delete [] bcol;
299 
300  // if fore or background have changed from previous character
301  // recalculate the 3 smoothing colors (interpolation between fore-
302  // and background colors)
303  if (fore != col[4].pixel || back != col[0].pixel) {
304  col[4].pixel = fore;
305  col[4].flags = DoRed|DoGreen|DoBlue;
306  if (back != (ULong_t) -1) {
307  col[3].pixel = back;
308  col[3].flags = DoRed | DoGreen | DoBlue;
309  QueryColors(fColormap, &col[3], 2);
310  col[0] = col[3];
311  } else {
312  QueryColors(fColormap, &col[4], 1);
313  }
314 
315  // interpolate between fore and background colors
316  for (x = 3; x > 0; x--) {
317  col[x].red = (col[4].red *x + col[0].red *(4-x)) /4;
318  col[x].green = (col[4].green*x + col[0].green*(4-x)) /4;
319  col[x].blue = (col[4].blue *x + col[0].blue *(4-x)) /4;
320  if (!AllocColor(fColormap, &col[x])) {
321  Warning("DrawImage", "cannot allocate smoothing color");
322  col[x].pixel = col[x+1].pixel;
323  }
324  }
325  }
326 
327  // put smoothed character, character pixmap values are an index
328  // into the 5 colors used for aliasing (4 = foreground, 0 = background)
329  for (y = 0; y < (int) source->rows; y++) {
330  for (x = 0; x < (int) source->width; x++) {
331  d = *s++ & 0xff;
332  d = ((d + 10) * 5) / 256;
333  if (d > 4) d = 4;
334  if (d && x < (int) source->width) {
335  ULong_t p = col[d].pixel;
336  XPutPixel(xim, bx + x, by + y, p);
337  }
338  }
339  }
340  } else {
341  // no smoothing, just put character using foreground color
342  UChar_t* row=s;
343  for (int y = 0; y < (int) source->rows; y++) {
344  int n = 0;
345  s = row;
346  for (int x = 0; x < (int) source->width; x++) {
347  if (n == 0) d = *s++;
348  if (TESTBIT(d,7-n))
349  XPutPixel(xim, bx + x, by + y, fore);
350  if (++n == (int) kBitsPerByte) n = 0;
351  }
352  row += source->pitch;
353  }
354  }
355 }
356 
357 ////////////////////////////////////////////////////////////////////////////////
358 /// Draw text using TrueType fonts. If TrueType fonts are not available the
359 /// text is drawn with TGX11::DrawText.
360 
362  const char *text, ETextMode mode)
363 {
364  if (!fHasTTFonts) {
365  TGX11::DrawText(x, y, angle, mgn, text, mode);
366  } else {
367  if (!TTF::fgInit) TTF::Init();
368  TTF::SetRotationMatrix(angle);
369  TTF::PrepareString(text);
371  Align();
372  RenderString(x, y, mode);
373  }
374 }
375 
376 ////////////////////////////////////////////////////////////////////////////////
377 /// Draw text using TrueType fonts. If TrueType fonts are not available the
378 /// text is drawn with TGX11::DrawText.
379 
381  const wchar_t *text, ETextMode mode)
382 {
383  if (!fHasTTFonts) {
384  TGX11::DrawText(x, y, angle, mgn, text, mode);
385  } else {
386  if (!TTF::fgInit) TTF::Init();
387  TTF::SetRotationMatrix(angle);
388  TTF::PrepareString(text);
390  Align();
391  RenderString(x, y, mode);
392  }
393 }
394 
395 ////////////////////////////////////////////////////////////////////////////////
396 /// Get the background of the current window in an XImage.
397 
399 {
400  Window_t cws = GetCurrentWindow();
401  UInt_t width;
402  UInt_t height;
403  Int_t xy;
404  gVirtualX->GetWindowSize(cws, xy, xy, width, height);
405 
406  if (x < 0) {
407  w += x;
408  x = 0;
409  }
410  if (y < 0) {
411  h += y;
412  y = 0;
413  }
414 
415  if (x+w > width) w = width - x;
416  if (y+h > height) h = height - y;
417 
418  return (RXImage*)XGetImage((Display*)fDisplay, cws, x, y, w, h, AllPlanes, ZPixmap);
419 }
420 
421 ////////////////////////////////////////////////////////////////////////////////
422 /// Test if there is really something to render.
423 
425 {
426  Window_t cws = GetCurrentWindow();
427  UInt_t width;
428  UInt_t height;
429  Int_t xy;
430  gVirtualX->GetWindowSize(cws, xy, xy, width, height);
431 
432  // If w or h is 0, very likely the string is only blank characters
433  if ((int)w == 0 || (int)h == 0) return kFALSE;
434 
435  // If string falls outside window, there is probably no need to draw it.
436  if (x + (int)w <= 0 || x >= (int)width) return kFALSE;
437  if (y + (int)h <= 0 || y >= (int)height) return kFALSE;
438 
439  // If w or h are much larger than the window size, there is probably no need
440  // to draw it. Moreover a to large text size may produce a Seg Fault in
441  // malloc in RenderString.
442  if (w > 10*width) return kFALSE;
443  if (h > 10*height) return kFALSE;
444 
445  return kTRUE;
446 }
447 
448 ////////////////////////////////////////////////////////////////////////////////
449 /// Perform the string rendering in the pad.
450 /// LayoutGlyphs should have been called before.
451 
453 {
454  TTF::TTGlyph* glyph = TTF::fgGlyphs;
455  GC *gc;
456 
457  // compute the size and position of the XImage that will contain the text
458  Int_t Xoff = 0; if (TTF::GetBox().xMin < 0) Xoff = -TTF::GetBox().xMin;
459  Int_t Yoff = 0; if (TTF::GetBox().yMin < 0) Yoff = -TTF::GetBox().yMin;
460  Int_t w = TTF::GetBox().xMax + Xoff;
461  Int_t h = TTF::GetBox().yMax + Yoff;
462  Int_t x1 = x-Xoff-fAlign.x;
463  Int_t y1 = y+Yoff+fAlign.y-h;
464 
465  if (!IsVisible(x1, y1, w, h)) return;
466 
467  // create the XImage that will contain the text
468  UInt_t depth = fDepth;
469  XImage *xim = 0;
470  xim = XCreateImage((Display*)fDisplay, fVisual,
471  depth, ZPixmap, 0, 0, w, h,
472  depth == 24 ? 32 : (depth==15?16:depth), 0);
473  if (!xim) return;
474 
475  // use malloc since Xlib will use free() in XDestroyImage
476  xim->data = (char *) malloc(xim->bytes_per_line * h);
477  memset(xim->data, 0, xim->bytes_per_line * h);
478 
479  ULong_t bg;
480  XGCValues values;
481  gc = (GC*)GetGC(3);
482  if (!gc) {
483  Error("DrawText", "error getting Graphics Context");
484  return;
485  }
486  XGetGCValues((Display*)fDisplay, *gc, GCForeground | GCBackground, &values);
487 
488  // get the background
489  if (mode == kClear) {
490  // if mode == kClear we need to get an image of the background
491  XImage *bim = GetBackground(x1, y1, w, h);
492  if (!bim) {
493  Error("DrawText", "error getting background image");
494  return;
495  }
496 
497  // and copy it into the text image
498  Int_t xo = 0, yo = 0;
499  if (x1 < 0) xo = -x1;
500  if (y1 < 0) yo = -y1;
501 
502  for (int yp = 0; yp < (int) bim->height; yp++) {
503  for (int xp = 0; xp < (int) bim->width; xp++) {
504  ULong_t pixel = XGetPixel(bim, xp, yp);
505  XPutPixel(xim, xo+xp, yo+yp, pixel);
506  }
507  }
508  XDestroyImage(bim);
509  bg = (ULong_t) -1;
510  } else {
511  // if mode == kOpaque its simple, we just draw the background
512  XAddPixel(xim, values.background);
513  bg = values.background;
514  }
515 
516  // paint the glyphs in the XImage
517  glyph = TTF::fgGlyphs;
518  for (int n = 0; n < TTF::fgNumGlyphs; n++, glyph++) {
519  if (FT_Glyph_To_Bitmap(&glyph->fImage,
520  TTF::fgSmoothing ? ft_render_mode_normal
521  : ft_render_mode_mono,
522  0, 1 )) continue;
523  FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyph->fImage;
524  FT_Bitmap* source = &bitmap->bitmap;
525  Int_t bx, by;
526 
527  bx = bitmap->left+Xoff;
528  by = h - bitmap->top-Yoff;
529  DrawImage(source, values.foreground, bg, (RXImage*)xim, bx, by);
530  }
531 
532  // put the Ximage on the screen
533  Window_t cws = GetCurrentWindow();
534  gc = (GC*)GetGC(6);
535  if (gc) XPutImage((Display*)fDisplay, cws, *gc, xim, 0, 0, x1, y1, w, h);
536  XDestroyImage(xim);
537 }
538 
539 ////////////////////////////////////////////////////////////////////////////////
540 /// Set specified font.
541 
543 {
544  fTextFont = fontnumber;
545  if (!fHasTTFonts) {
546  TGX11::SetTextFont(fontnumber);
547  } else {
548  TTF::SetTextFont(fontnumber);
549  }
550 }
551 
552 ////////////////////////////////////////////////////////////////////////////////
553 /// Set text font to specified name.
554 /// mode : loading flag
555 /// mode=0 : search if the font exist (kCheck)
556 /// mode=1 : search the font and load it if it exists (kLoad)
557 /// font : font name
558 ///
559 /// Set text font to specified name. This function returns 0 if
560 /// the specified font is found, 1 if not.
561 
563 {
564  if (!fHasTTFonts) {
565  return TGX11::SetTextFont(fontname, mode);
566  } else {
567  return TTF::SetTextFont(fontname);
568  }
569 }
570 
571 ////////////////////////////////////////////////////////////////////////////////
572 /// Set current text size.
573 
575 {
576  fTextSize = textsize;
577  if (!fHasTTFonts) {
578  TGX11::SetTextSize(textsize);
579  } else {
580  TTF::SetTextSize(textsize);
581  }
582 }
583 
584 #ifdef R__HAS_XFT
585 
586 ///////////////////////////// Xft font methods /////////////////////////////////
587 ////////////////////////////////////////////////////////////////////////////////
588 /// Parses an XLFD name and opens a font.
589 
590 FontStruct_t TGX11TTF::LoadQueryFont(const char *font_name)
591 {
592  if (!fXftFontHash) {
593  return TGX11::LoadQueryFont(font_name);
594  }
595 
596  TXftFontData *data = fXftFontHash->FindByName(font_name);
597 
598  // already loaded
599  if (data) {
600  data->AddReference();
601  return (FontStruct_t)data->fXftFont;
602  }
603 
604  XftFont *xftfont = XftFontOpenXlfd((Display*)fDisplay, fScreenNumber, font_name);
605 
606  data = new TXftFontData(0, xftfont, font_name);
607  fXftFontHash->AddFont(data);
608 
609  return (FontStruct_t)xftfont;
610 }
611 
612 ////////////////////////////////////////////////////////////////////////////////
613 /// Explicitly delete font structure obtained with LoadQueryFont().
614 
616 {
617  if (!fXftFontHash) {
618  TGX11::DeleteFont(fs);
619  return;
620  }
621 
622  TXftFontData *data = fXftFontHash->FindByFont(fs);
623 
624  if (data)
625  fXftFontHash->FreeFont(data);
626 }
627 
628 ////////////////////////////////////////////////////////////////////////////////
629 /// Explicitly delete a graphics context.
630 
632 {
633  if (!fXftFontHash) {
634  TGX11::DeleteGC(gc);
635  return;
636  }
637 
638  TXftFontData *gcdata = fXftFontHash->FindByGC(gc);
639  if (gcdata) fXftFontHash->FreeFont(gcdata);
640  TGX11::DeleteGC(gc);
641 }
642 
643 ////////////////////////////////////////////////////////////////////////////////
644 /// Return handle to font described by font structure.
645 
647 {
648  if (!fXftFontHash) {
649  return TGX11::GetFontHandle(fs);
650  }
651 
652  return (FontH_t)fs;
653 }
654 
655 ////////////////////////////////////////////////////////////////////////////////
656 /// Return the font associated with the graphics context gc
657 
659 {
660  if (!fXftFontHash) {
661  return 0;
662  }
663 
664  TXftFontData *data = fXftFontHash->FindByGC(gc);
665 
666  // no XftFont data
667  if (!data) return 0;
668 
669  return (FontStruct_t)data->fXftFont;
670 }
671 
672 ////////////////////////////////////////////////////////////////////////////////
673 /// Map the XftFont with the Graphics Context using it.
674 
676 {
677  if (!fXftFontHash)
678  return;
679 
680  TXftFontData *gcdata = fXftFontHash->FindByGC(gc);
681  TXftFontData *fontdata = fXftFontHash->FindByFont(font);
682 
683  if (gcdata) { // && (gcdata->fXftFont == 0)) {
684  gcdata->fXftFont = (XftFont *)font;
685  }
686  else if (fontdata) {
687  TXftFontData *data = new TXftFontData(gc, (XftFont *)font, fontdata->GetName());
688  fXftFontHash->AddFont(data);
689  }
690 }
691 
692 ////////////////////////////////////////////////////////////////////////////////
693 /// Return length of string in pixels. Size depends on font
694 
695 Int_t TGX11TTF::TextWidth(FontStruct_t font, const char *s, Int_t len)
696 {
697  if (!fXftFontHash) {
698  return TGX11::TextWidth(font, s, len);
699  }
700 
701  TXftFontData *data = fXftFontHash->FindByFont(font);
702 
703  if (!data) return 0;
704 
705  XftFont *xftfont = data->fXftFont;
706 
707  if (xftfont) {
708  XGlyphInfo glyph_info;
709  XftTextExtents8((Display *)fDisplay, xftfont, (XftChar8 *)s, len, &glyph_info);
710  return glyph_info.xOff;
711  }
712  return 0;
713 }
714 
715 ////////////////////////////////////////////////////////////////////////////////
716 /// Return some font properties
717 
718 void TGX11TTF::GetFontProperties(FontStruct_t font, Int_t &max_ascent, Int_t &max_descent)
719 {
720  if (!fXftFontHash) {
721  TGX11::GetFontProperties(font, max_ascent, max_descent);
722  return;
723  }
724 
725  TXftFontData *data = fXftFontHash->FindByFont(font);
726 
727  if (!data) {
728  TGX11::GetFontProperties(font, max_ascent, max_descent);
729  return;
730  }
731 
732  XftFont *xftfont = data->fXftFont;
733 
734  if (!xftfont) {
735  TGX11::GetFontProperties(font, max_ascent, max_descent);
736  return;
737  }
738 
739  max_ascent = xftfont->ascent;
740  max_descent = xftfont->descent;
741 }
742 
743 ////////////////////////////////////////////////////////////////////////////////
744 /// Draw text string
745 
746 void TGX11TTF::DrawString(Drawable_t xwindow, GContext_t gc, Int_t x, Int_t y,
747  const char *text, Int_t len)
748 {
749  XftDraw *xftdraw;
750  XftColor xftcolor;
751  XColor xcolor;
752  XftFont *xftfont;
753 
754  if (!xwindow) {
755  return;
756  }
757 
758  if (!gc) {
759  return;
760  }
761 
762  if (!text || (len < 1) || !text[0]) {
763  return;
764  }
765 
766  if (!fXftFontHash) {
767  TGX11::DrawString(xwindow, gc, x, y, text, len);
768  return;
769  }
770 
771  GCValues_t gval;
772  gval.fMask = kGCForeground | kGCBackground; // retrieve GC values
773  GetGCValues(gc, gval);
774 
775  TXftFontData *data = fXftFontHash->FindByGC(gc);
776 
777  // no XftFont data
778  if (!data) {
779  TGX11::DrawString(xwindow, gc, x, y, text, len);
780  return;
781  }
782 
783  xftfont = data->fXftFont;
784 
785  // no Xft font
786  if (!xftfont) {
787  TGX11::DrawString(xwindow, gc, x, y, text, len);
788  return;
789  }
790 
791  // dummies
792  Window droot;
793  Int_t dx,dy;
794  UInt_t bwidth, width, height, depth;
795 
796  // check if drawable is bitmap
797  XGetGeometry((Display*)fDisplay, (Drawable)xwindow, &droot, &dx, &dy,
798  &width, &height, &bwidth, &depth);
799 
800  if (depth <= 1) {
801  TGX11::DrawString(xwindow, gc, x, y, text, len);
802  return;
803  }
804 
805  memset(&xcolor, 0, sizeof(xcolor));
806  xcolor.pixel = gval.fForeground;
807 
808  XQueryColor((Display*)fDisplay, fColormap, &xcolor);
809 
810  // create XftDraw
811  xftdraw = XftDrawCreate((Display*)fDisplay, (Drawable)xwindow, fVisual, fColormap);
812 
813  if (!xftdraw) {
814  //Warning("could not create an XftDraw");
815  TGX11::DrawString(xwindow, gc, x, y, text, len);
816  return;
817  }
818 
819  xftcolor.color.red = xcolor.red;
820  xftcolor.color.green = xcolor.green;
821  xftcolor.color.blue = xcolor.blue;
822  xftcolor.color.alpha = 0xffff;
823  xftcolor.pixel = gval.fForeground;
824 
825  XftDrawString8(xftdraw, &xftcolor, xftfont, x, y, (XftChar8 *)text, len);
826 
827  // cleanup
828  XftDrawDestroy(xftdraw);
829 }
830 
831 #endif // R__HAS_XFT
832 
static void Activate()
Static method setting TGX11TTF as the acting gVirtualX.
Definition: TGX11TTF.cxx:166
void GetGCValues(GContext_t gc, GCValues_t &gval)
Get current values from graphics context gc.
Definition: GX11Gui.cxx:2101
void * fDisplay
Pointer to display.
Definition: TGX11.h:130
Handle_t FontStruct_t
Definition: GuiTypes.h:40
static void Init()
Initialise the TrueType fonts interface.
Definition: TTF.cxx:67
XID Drawable
Definition: TGX11.h:38
void DeleteFont(FontStruct_t fs)
Explicitly delete font structure obtained with LoadQueryFont().
Definition: GX11Gui.cxx:976
static FT_Matrix * fgRotMatrix
Definition: TTF.h:99
ClassImp(TSeqCollection) Int_t TSeqCollection TIter next(this)
Return index of object in collection.
float Float_t
Definition: RtypesCore.h:53
Bool_t Init(void *display)
Initialize X11 system. Returns kFALSE in case of failure.
Definition: TGX11.cxx:337
Bool_t fHasXft
True when XftFonts are used.
Definition: TGX11.h:152
Int_t fScreenNumber
Screen number.
Definition: TGX11.h:137
FT_Glyph fImage
Definition: TTF.h:79
unsigned short UShort_t
Definition: RtypesCore.h:36
TH1 * h
Definition: legend2.C:5
Definitions for TRefCnt, base class for reference counted objects.
Definition: TRefCnt.h:29
Handle_t GContext_t
Definition: GuiTypes.h:39
void DrawImage(FT_Bitmap *source, ULong_t fore, ULong_t back, RXImage *xim, Int_t bx, Int_t by)
Draw FT_Bitmap bitmap to xim image at position bx,by using specified foreground color.
Definition: TGX11TTF.cxx:238
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
Handle_t Drawable_t
Definition: GuiTypes.h:32
short Font_t
Definition: RtypesCore.h:75
Int_t fTextAlign
Text alignment (set in SetTextAlign)
Definition: TGX11.h:140
Interface to low level X11 (Xlib).
Definition: TGX11TTF.h:45
static Int_t fgAscent
Definition: TTF.h:85
FT_Vector fAlign
Definition: TGX11TTF.h:51
Handle_t FontH_t
Definition: GuiTypes.h:36
virtual void SetValue(const char *name, const char *value, EEnvLevel level=kEnvChange, const char *type=0)
Set the value of a resource or create a new resource.
Definition: TEnv.cxx:749
virtual Int_t SetTextFont(char *fontname, ETextSetMode mode)
Set text font to specified name.
Definition: TGX11.cxx:2901
void * GetGC(Int_t which) const
Return desired Graphics Context ("which" maps directly on gGCList[]).
Definition: TGX11.cxx:926
THashTable implements a hash table to store TObject's.
Definition: THashTable.h:39
static TTF::TTGlyph fgGlyphs[kMaxGlyphs]
Definition: TTF.h:93
Double_t x[n]
Definition: legend1.C:17
static void LayoutGlyphs()
Compute the glyphs positions, fgAscent and fgWidth (needed for alignment).
Definition: TTF.cxx:183
Window_t GetCurrentWindow() const
Return current window pointer. Protected method used by TGX11TTF.
Definition: TGX11.cxx:917
static void SetTextFont(Font_t fontnumber)
Set specified font.
Definition: TTF.cxx:496
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:33
static void PrepareString(const char *string)
Put the characters in "string" in the "glyphs" array.
Definition: TTF.cxx:249
ULong_t fForeground
Definition: GuiTypes.h:228
Colormap fColormap
Default colormap, 0 if b/w.
Definition: TGX11.h:134
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
void QueryColors(Colormap cmap, RXColor *colors, Int_t ncolors)
Returns the current RGB value for the pixel in the XColor structure.
Definition: TGX11.cxx:378
Int_t fDepth
Number of color planes.
Definition: TGX11.h:144
static void SetSmoothing(Bool_t state)
Set smoothing (anti-aliasing) flag.
Definition: TTF.cxx:364
void SetRefCount(UInt_t r)
Definition: TRefCnt.h:41
void GetFontProperties(FontStruct_t font, Int_t &max_ascent, Int_t &max_descent)
Return some font properties.
Definition: GX11Gui.cxx:2088
virtual void DrawText(Int_t x, Int_t y, Float_t angle, Float_t mgn, const char *text, ETextMode mode)
Draw a text string using current font.
Definition: TGX11.cxx:746
ROOT::R::TRInterface & r
Definition: Object.C:4
XPoint xy[kMAXMK]
Definition: TGX11.cxx:122
void SetTextSize(Float_t textsize)
Set current text size.
Definition: TGX11TTF.cxx:574
FontH_t GetFontHandle(FontStruct_t fs)
Return handle to font described by font structure.
Definition: GX11Gui.cxx:964
virtual Int_t GetValue(const char *name, Int_t dflt)
Returns the integer value for a resource.
Definition: TEnv.cxx:494
void DrawString(Drawable_t id, GContext_t gc, Int_t x, Int_t y, const char *s, Int_t len)
Draw a string using a specific graphics context in position (x,y).
Definition: GX11Gui.cxx:2069
static Bool_t fgInit
Definition: TTF.h:95
void DrawText(Int_t x, Int_t y, Float_t angle, Float_t mgn, const char *text, ETextMode mode)
Draw text using TrueType fonts.
Definition: TGX11TTF.cxx:361
FontStruct_t LoadQueryFont(const char *font_name)
Load font and query font.
Definition: GX11Gui.cxx:955
unsigned int UInt_t
Definition: RtypesCore.h:42
TTF helper class containing glyphs description.
Definition: TTF.h:75
Bool_t fHasTTFonts
True when TrueType fonts are used.
Definition: TGX11.h:151
virtual FontStruct_t GetGCFont(GContext_t gc)
Return the font associated with the graphics context gc.
Definition: TVirtualX.cxx:1843
TGX11TTF(const TGX11 &org)
void SetTextFont(Font_t fontnumber)
Set specified font.
Definition: TGX11TTF.cxx:542
Font_t fTextFont
Definition: TAttText.h:39
#define gVirtualX
Definition: TVirtualX.h:362
This class is the basic interface to the X11 (Xlib) graphics system.
Definition: TGX11.h:85
void RenderString(Int_t x, Int_t y, ETextMode mode)
Perform the string rendering in the pad.
Definition: TGX11TTF.cxx:452
XID Window
Definition: TGX11.h:41
virtual void SetTextSize(Float_t textsize)
Set current text size.
Definition: TGX11.cxx:2950
static const double x1[5]
R__EXTERN TEnv * gEnv
Definition: TEnv.h:174
unsigned long ULong_t
Definition: RtypesCore.h:51
Double_t y[n]
Definition: legend1.C:17
Bool_t AllocColor(Colormap cmap, RXColor *color)
Allocate color in colormap.
Definition: TGX11.cxx:361
void Add(TObject *obj)
Add object to the hash table.
Definition: THashTable.cxx:75
static TTFX11Init gTTFX11Init
Definition: TGX11TTF.cxx:138
const Mask_t kGCForeground
Definition: GuiTypes.h:289
Float_t fTextSize
Definition: TAttText.h:36
void Align(void)
Compute alignment variables.
Definition: TGX11TTF.cxx:207
void DeleteGC(GContext_t gc)
Explicitly delete a graphics context.
Definition: GX11Gui.cxx:1046
#define org(otri, vertexptr)
Definition: triangle.c:1037
static Bool_t fgSmoothing
Definition: TTF.h:100
static void SetRotationMatrix(Float_t angle)
Set the rotation matrix used to rotate the font outlines.
Definition: TTF.cxx:341
Handle_t Window_t
Definition: GuiTypes.h:30
Mask_t fMask
Definition: GuiTypes.h:252
const size_t kBitsPerByte
Definition: Rtypes.h:114
RVisual * fVisual
Pointer to visual used by all windows.
Definition: TGX11.h:131
const Mask_t kGCBackground
Definition: GuiTypes.h:290
virtual void MapGCFont(GContext_t, FontStruct_t)
Map the XftFont with the Graphics Context using it.
Definition: TVirtualX.cxx:2503
Bool_t Init(void *display)
Initialize X11 system. Returns kFALSE in case of failure.
Definition: TGX11TTF.cxx:178
TObject * FindObject(const char *name) const
Find object using its name.
Definition: THashTable.cxx:209
Bool_t IsVisible(Int_t x, Int_t y, UInt_t w, UInt_t h)
Test if there is really something to render.
Definition: TGX11TTF.cxx:424
#define TESTBIT(n, i)
Definition: Rtypes.h:123
static Int_t fgNumGlyphs
Definition: TTF.h:98
static void SetTextSize(Float_t textsize)
Set current text size.
Definition: TTF.cxx:572
unsigned char UChar_t
Definition: RtypesCore.h:34
ClassImp(TGX11TTF) TGX11TTF
Create copy of TGX11 but now use TrueType fonts.
Definition: TGX11TTF.cxx:141
RXImage * GetBackground(Int_t x, Int_t y, UInt_t w, UInt_t h)
Get the background of the current window in an XImage.
Definition: TGX11TTF.cxx:398
const Bool_t kTRUE
Definition: Rtypes.h:91
Vc_ALWAYS_INLINE_L T *Vc_ALWAYS_INLINE_R malloc(size_t n)
Allocates memory on the Heap with alignment and padding suitable for vectorized access.
Definition: memory.h:67
Int_t TextWidth(FontStruct_t font, const char *s, Int_t len)
Return length of string in pixels. Size depends on font.
Definition: GX11Gui.cxx:2080
const Int_t n
Definition: legend1.C:16
gr SetName("gr")
static Int_t fgWidth
Definition: TTF.h:102
static const FT_BBox & GetBox()
Definition: TTF.cxx:653
TObject * Remove(TObject *obj)
Remove object from the hashtable.
Definition: THashTable.cxx:314
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:904