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