Logo ROOT   6.10/00
Reference Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
TTF.cxx
Go to the documentation of this file.
1 // @(#)root/graf:$Id$
2 // Author: Olivier Couet 01/10/02
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /** \class TTF
13 \ingroup BasicGraphics
14 
15 Interface to the freetype 2 library.
16 */
17 
18 # include <ft2build.h>
19 # include FT_FREETYPE_H
20 # include FT_GLYPH_H
21 #include "TROOT.h"
22 #include "TTF.h"
23 #include "TSystem.h"
24 #include "TEnv.h"
25 #include "TMath.h"
26 #include "TError.h"
27 
28 #include <fontconfig/fontconfig.h>
29 
30 // to scale fonts to the same size as the old TT version
31 const Float_t kScale = 0.93376068;
32 
33 TTF gCleanupTTF; // Allows to call "Cleanup" at the end of the session
34 
45 Int_t TTF::fgFontID[kTTMaxFonts];
46 FT_Matrix *TTF::fgRotMatrix;
47 FT_Library TTF::fgLibrary;
48 FT_BBox TTF::fgCBox;
49 FT_Face TTF::fgFace[kTTMaxFonts];
50 FT_CharMap TTF::fgCharMap[kTTMaxFonts];
51 TTF::TTGlyph TTF::fgGlyphs[kMaxGlyphs];
52 
54 
55 ////////////////////////////////////////////////////////////////////////////////
56 /// Cleanup TTF environment.
57 
58 TTF::~TTF()
59 {
60  Cleanup();
61 }
62 
63 ////////////////////////////////////////////////////////////////////////////////
64 /// Initialise the TrueType fonts interface.
65 
66 void TTF::Init()
67 {
68  fgInit = kTRUE;
69 
70  // initialize FTF library
71  if (FT_Init_FreeType(&fgLibrary)) {
72  Error("TTF::Init", "error initializing FreeType");
73  return;
74  }
75 
76  // Add root's font directory
77  const char *ttpath = gEnv->GetValue("Root.TTFontPath",
79  FcConfigAppFontAddDir (NULL, (const FcChar8*)ttpath);
80 
81  // load default font (arialbd)
82  SetTextFont(62);
83 }
84 
85 ////////////////////////////////////////////////////////////////////////////////
86 /// Cleanup. Is called by the gCleanupTTF destructor.
87 
89 {
90  if (!fgInit) return;
91 
92  for (int i = 0; i < fgFontCount; i++) {
93  FT_Done_Face(fgFace[i]);
94  }
95  if (fgRotMatrix) delete fgRotMatrix;
96  FT_Done_FreeType(fgLibrary);
97 
98  fgInit = kFALSE;
99 }
100 
101 ////////////////////////////////////////////////////////////////////////////////
102 /// Map char to unicode. Returns 0 in case no mapping exists.
103 
105 {
106  if (!fgCharMap[fgCurFontIdx]) {
107  UShort_t i, platform, encoding;
108  FT_CharMap charmap;
109 
110  if (!fgFace[fgCurFontIdx]) return 0;
111  Int_t n = fgFace[fgCurFontIdx]->num_charmaps;
112  for (i = 0; i < n; i++) {
113  if (!fgFace[fgCurFontIdx]) continue;
114  charmap = fgFace[fgCurFontIdx]->charmaps[i];
115  platform = charmap->platform_id;
116  encoding = charmap->encoding_id;
117  if ((platform == 3 && encoding == 1 &&
118  (fgFontID[fgCurFontIdx] != 12 &&
119  fgFontID[fgCurFontIdx] != 14 &&
120  fgFontID[fgCurFontIdx] != 15)) ||
121  (platform == 0 && encoding == 0) ||
122  (platform == 7 && encoding == 2 &&
123  (fgFontID[fgCurFontIdx] == 12 ||
124  fgFontID[fgCurFontIdx] == 14 ||
125  fgFontID[fgCurFontIdx] == 15)) ||
126  (platform == 1 && encoding == 0 &&
127  (fgFontID[fgCurFontIdx] == 12 ||
128  fgFontID[fgCurFontIdx] == 14 ||
129  fgFontID[fgCurFontIdx] == 15)))
130  {
131  fgCharMap[fgCurFontIdx] = charmap;
132  if (FT_Set_Charmap(fgFace[fgCurFontIdx], fgCharMap[fgCurFontIdx]))
133  Error("TTF::CharToUnicode", "error in FT_Set_CharMap");
134  return FT_Get_Char_Index(fgFace[fgCurFontIdx], (FT_ULong)code);
135  }
136  }
137  }
138  return FT_Get_Char_Index(fgFace[fgCurFontIdx], (FT_ULong)code);
139 }
140 
141 ////////////////////////////////////////////////////////////////////////////////
142 /// Get width (w) and height (h) when text is horizontal.
143 
145 {
146  if (!fgInit) Init();
147 
149  PrepareString(text);
150  LayoutGlyphs();
151  Int_t Xoff = 0; if (fgCBox.xMin < 0) Xoff = -fgCBox.xMin;
152  Int_t Yoff = 0; if (fgCBox.yMin < 0) Yoff = -fgCBox.yMin;
153  w = fgCBox.xMax + Xoff + fgTBlankW;
154  h = fgCBox.yMax + Yoff;
155 }
156 
157 ////////////////////////////////////////////////////////////////////////////////
158 /// Get advance (a) when text is horizontal.
159 
161 {
162  if (!fgInit) Init();
163 
165  PrepareString(text);
166  LayoutGlyphs();
167  a = GetWidth()>>6;
168 }
169 
170 ////////////////////////////////////////////////////////////////////////////////
171 /// Get width (w) and height (h) when text is horizontal.
172 
173 void TTF::GetTextExtent(UInt_t &w, UInt_t &h, wchar_t *text)
174 {
175  if (!fgInit) Init();
176 
178  PrepareString(text);
179  LayoutGlyphs();
180  Int_t Xoff = 0; if (fgCBox.xMin < 0) Xoff = -fgCBox.xMin;
181  Int_t Yoff = 0; if (fgCBox.yMin < 0) Yoff = -fgCBox.yMin;
182  w = fgCBox.xMax + Xoff + fgTBlankW;
183  h = fgCBox.yMax + Yoff;
184 }
185 
186 ////////////////////////////////////////////////////////////////////////////////
187 /// Compute the glyphs positions, fgAscent and fgWidth (needed for alignment).
188 /// Perform the Glyphs transformation.
189 /// Compute the string control box.
190 /// If required take the "kerning" into account.
191 /// SetRotation and PrepareString should have been called before.
192 
194 {
195  TTGlyph* glyph = fgGlyphs;
196  FT_Vector origin;
197  FT_UInt load_flags;
198  FT_UInt prev_index = 0;
199 
200  fgAscent = 0;
201  fgWidth = 0;
202 
203  load_flags = FT_LOAD_DEFAULT;
204  if (!fgHinting) load_flags |= FT_LOAD_NO_HINTING;
205 
206  fgCBox.xMin = fgCBox.yMin = 32000;
207  fgCBox.xMax = fgCBox.yMax = -32000;
208 
209  for (int n = 0; n < fgNumGlyphs; n++, glyph++) {
210 
211  // compute glyph origin
212  if (fgKerning) {
213  if (prev_index) {
214  FT_Vector kern;
215  FT_Get_Kerning(fgFace[fgCurFontIdx], prev_index, glyph->fIndex,
216  fgHinting ? ft_kerning_default : ft_kerning_unfitted,
217  &kern);
218  fgWidth += kern.x;
219  }
220  prev_index = glyph->fIndex;
221  }
222 
223  origin.x = fgWidth;
224  origin.y = 0;
225 
226  // clear existing image if there is one
227  if (glyph->fImage) FT_Done_Glyph(glyph->fImage);
228 
229  // load the glyph image (in its native format)
230  if (FT_Load_Glyph(fgFace[fgCurFontIdx], glyph->fIndex, load_flags))
231  continue;
232 
233  // extract the glyph image
234  if (FT_Get_Glyph (fgFace[fgCurFontIdx]->glyph, &glyph->fImage))
235  continue;
236 
237  glyph->fPos = origin;
238  fgWidth += fgFace[fgCurFontIdx]->glyph->advance.x;
239  fgAscent = TMath::Max((Int_t)(fgFace[fgCurFontIdx]->glyph->metrics.horiBearingY), fgAscent);
240 
241  // transform the glyphs
242  FT_Vector_Transform(&glyph->fPos, fgRotMatrix);
243  if (FT_Glyph_Transform(glyph->fImage, fgRotMatrix, &glyph->fPos))
244  continue;
245 
246  // compute the string control box
247  FT_BBox bbox;
248  FT_Glyph_Get_CBox(glyph->fImage, ft_glyph_bbox_pixels, &bbox);
249  if (bbox.xMin < fgCBox.xMin) fgCBox.xMin = bbox.xMin;
250  if (bbox.yMin < fgCBox.yMin) fgCBox.yMin = bbox.yMin;
251  if (bbox.xMax > fgCBox.xMax) fgCBox.xMax = bbox.xMax;
252  if (bbox.yMax > fgCBox.yMax) fgCBox.yMax = bbox.yMax;
253  }
254 }
255 
256 ////////////////////////////////////////////////////////////////////////////////
257 /// Put the characters in "string" in the "glyphs" array.
258 
259 void TTF::PrepareString(const char *string)
260 {
261  const unsigned char *p = (const unsigned char*) string;
262  TTGlyph *glyph = fgGlyphs;
263  UInt_t index; // Unicode value
264  Int_t NbTBlank = 0; // number of trailing blanks
265 
266  fgTBlankW = 0;
267  fgNumGlyphs = 0;
268  while (*p) {
269  index = CharToUnicode((FT_ULong)*p);
270  if (index != 0) {
271  glyph->fIndex = index;
272  glyph++;
273  fgNumGlyphs++;
274  }
275  if (*p == ' ') {
276  NbTBlank++;
277  } else {
278  NbTBlank = 0;
279  }
280  if (fgNumGlyphs >= kMaxGlyphs) break;
281  p++;
282  }
283 
284  // compute the trailing blanks width. It is use to compute the text
285  // width in GetTextExtent
286  if (NbTBlank) {
287  FT_UInt load_flags = FT_LOAD_DEFAULT;
288  if (!fgHinting) load_flags |= FT_LOAD_NO_HINTING;
289  if (FT_Load_Glyph(fgFace[fgCurFontIdx], 3, load_flags)) return;
290  fgTBlankW = (Int_t)((fgFace[fgCurFontIdx]->glyph->advance.x)>>6)*NbTBlank;
291  }
292 }
293 
294 ////////////////////////////////////////////////////////////////////////////////
295 /// Put the characters in "string" in the "glyphs" array.
296 
297 void TTF::PrepareString(const wchar_t *string)
298 {
299  const wchar_t *p = string;
300  TTGlyph *glyph = fgGlyphs;
301  UInt_t index; // Unicode value
302  Int_t NbTBlank = 0; // number of trailing blanks
303 
304  fgTBlankW = 0;
305  fgNumGlyphs = 0;
306  while (*p) {
307  index = FT_Get_Char_Index(fgFace[fgCurFontIdx], (FT_ULong)*p);
308  if (index != 0) {
309  glyph->fIndex = index;
310  glyph++;
311  fgNumGlyphs++;
312  }
313  if (*p == ' ') {
314  NbTBlank++;
315  } else {
316  NbTBlank = 0;
317  }
318  if (fgNumGlyphs >= kMaxGlyphs) break;
319  p++;
320  }
321 
322  // compute the trailing blanks width. It is use to compute the text
323  // width in GetTextExtent
324  if (NbTBlank) {
325  FT_UInt load_flags = FT_LOAD_DEFAULT;
326  if (!fgHinting) load_flags |= FT_LOAD_NO_HINTING;
327  if (FT_Load_Glyph(fgFace[fgCurFontIdx], 3, load_flags)) return;
328  fgTBlankW = (Int_t)((fgFace[fgCurFontIdx]->glyph->advance.x)>>6)*NbTBlank;
329  }
330 }
331 
332 ////////////////////////////////////////////////////////////////////////////////
333 /// Set hinting flag.
334 
336 {
337  fgHinting = state;
338 }
339 
340 ////////////////////////////////////////////////////////////////////////////////
341 /// Set kerning flag.
342 
344 {
345  fgKerning = state;
346 }
347 
348 ////////////////////////////////////////////////////////////////////////////////
349 /// Set the rotation matrix used to rotate the font outlines.
350 
352 {
353  Float_t rangle = Float_t(angle * TMath::Pi() / 180.); // Angle in radian
354 #if defined(FREETYPE_PATCH) && \
355  (FREETYPE_MAJOR == 2) && (FREETYPE_MINOR == 1) && (FREETYPE_PATCH == 2)
356  Float_t sin = TMath::Sin(rangle);
357  Float_t cos = TMath::Cos(rangle);
358 #else
359  Float_t sin = TMath::Sin(-rangle);
360  Float_t cos = TMath::Cos(-rangle);
361 #endif
362 
363  if (!fgRotMatrix) fgRotMatrix = new FT_Matrix;
364 
365  fgRotMatrix->xx = (FT_Fixed) (cos * (1<<16));
366  fgRotMatrix->xy = (FT_Fixed) (sin * (1<<16));
367  fgRotMatrix->yx = -fgRotMatrix->xy;
368  fgRotMatrix->yy = fgRotMatrix->xx;
369 }
370 
371 ////////////////////////////////////////////////////////////////////////////////
372 /// Set smoothing (anti-aliasing) flag.
373 
375 {
376  fgSmoothing = state;
377 }
378 
379 ////////////////////////////////////////////////////////////////////////////////
380 /// Set text font to specified name.
381 /// - font : font name
382 /// - italic : the fonts should be slanted. Used for symbol font.
383 ///
384 /// Set text font to specified name. This function returns 0 if
385 /// the specified font is found, 1 if not.
386 
387 Int_t TTF::SetTextFont(const char *fontname, Int_t italic)
388 {
389  if (!fgInit) Init();
390 
391  if (!fontname || !fontname[0]) {
392  Warning("TTF::SetTextFont",
393  "no font name specified, using default font");
394  fgCurFontIdx = 0;
395  return 0;
396  }
397  const char *basename = gSystem->BaseName(fontname);
398 
399  if (strcmp(basename, "timesi.ttf") == 0 ||
400  strcmp(basename, "FreeSerifItalic.otf") == 0) {
401  SetTextFont(12);
402  }
403  else if (strcmp(basename, "timesbd.ttf") == 0 ||
404  strcmp(basename, "FreeSerifBold.otf") == 0) {
405  SetTextFont(22);
406  }
407  else if (strcmp(basename, "timesbi.ttf") == 0 ||
408  strcmp(basename, "FreeSerifBoldItalic.otf") == 0) {
409  SetTextFont(32);
410  }
411  else if (strcmp(basename, "arial.ttf") == 0 ||
412  strcmp(basename, "FreeSans.otf") == 0) {
413  SetTextFont(42);
414  }
415  else if (strcmp(basename, "ariali.ttf") == 0 ||
416  strcmp(basename, "FreeSansOblique.otf") == 0) {
417  SetTextFont(52);
418  }
419  else if (strcmp(basename, "arialbd.ttf") == 0 ||
420  strcmp(basename, "FreeSansBold.otf") == 0) {
421  SetTextFont(62);
422  }
423  else if (strcmp(basename, "arialbi.ttf") == 0 ||
424  strcmp(basename, "FreeSansBoldOblique.otf") == 0) {
425  SetTextFont(72);
426  }
427  else if (strcmp(basename, "cour.ttf") == 0 ||
428  strcmp(basename, "FreeMono.otf") == 0) {
429  SetTextFont(82);
430  }
431  else if (strcmp(basename, "couri.ttf") == 0 ||
432  strcmp(basename, "FreeMonoOblique.otf") == 0) {
433  SetTextFont(92);
434  }
435  else if (strcmp(basename, "courbd.ttf") == 0 ||
436  strcmp(basename, "FreeMonoBold.otf") == 0) {
437  SetTextFont(102);
438  }
439  else if (strcmp(basename, "courbi.ttf") == 0 ||
440  strcmp(basename, "FreeMonoBoldOblique.otf") == 0) {
441  SetTextFont(112);
442  }
443  else if (strcmp(basename, "symbol.ttf") == 0) {
444  if (italic)
445  SetTextFont(152);
446  else
447  SetTextFont(122);
448  }
449  else if (strcmp(basename, "times.ttf") == 0 ||
450  strcmp(basename, "FreeSerif.otf") == 0) {
451  SetTextFont(132);
452  }
453  else if (strcmp(basename, "wingding.ttf") == 0) {
454  SetTextFont(142);
455  }
456  else if (strcmp(basename, "STIXGeneral.otf") == 0) {
457  SetTextFont(162);
458  }
459  else if (strcmp(basename, "STIXGeneralItalic.otf") == 0) {
460  SetTextFont(172);
461  }
462  else if (strcmp(basename, "STIXGeneralBol.otf") == 0) {
463  SetTextFont(182);
464  }
465  else if (strcmp(basename, "STIXGeneralBolIta.otf") == 0) {
466  SetTextFont(192);
467  }
468  else if (strcmp(basename, "STIXSiz1Sym.otf") == 0) {
469  SetTextFont(202);
470  }
471  else if (strcmp(basename, "STIXSiz1SymBol.otf") == 0) {
472  SetTextFont(212);
473  }
474  else if (strcmp(basename, "STIXSiz2Sym.otf") == 0) {
475  SetTextFont(222);
476  }
477  else if (strcmp(basename, "STIXSiz2SymBol.otf") == 0) {
478  SetTextFont(232);
479  }
480  else if (strcmp(basename, "STIXSiz3Sym.otf") == 0) {
481  SetTextFont(242);
482  }
483  else if (strcmp(basename, "STIXSiz3SymBol.otf") == 0) {
484  SetTextFont(252);
485  }
486  else if (strcmp(basename, "STIXSiz4Sym.otf") == 0) {
487  SetTextFont(262);
488  }
489  else if (strcmp(basename, "STIXSiz4SymBol.otf") == 0) {
490  SetTextFont(272);
491  }
492  else if (strcmp(basename, "STIXSiz5Sym.otf") == 0) {
493  SetTextFont(282);
494  }
495  else if (strcmp(basename, "DroidSansFallback.ttf") == 0) {
496  SetTextFont(292);
497  }
498  else {
499  Error("TTF::SetTextFont", "font %s not known to ROOT", basename);
500  if (fgFontCount) {
501  Warning("TTF::SetTextFont", "using default font");
502  fgCurFontIdx = 0; // use font 0 (default font, set in ctor)
503  return 0;
504  } else {
505  return 1;
506  }
507  }
508 
509  return 0;
510 }
511 
512 //______________________________________________________________________________
513 void TTF::SetTextFont(Font_t fontnumber)
514 {
515  int fontid = fontnumber / 10;
516  if (fontid < 0 || fontid > 31) fontid = 0;
517 
518  Int_t italic = 0;
519  if (fontid==15) italic = 1;
520 
521  if (!fgInit) Init();
522 
523  if (fontid == 0) {
524  fgCurFontIdx = 0; // use font 0 (default font, set in ctor)
525  return;
526  }
527 
528  // check if font is in cache
529  int i;
530  for (i = 0; i < fgFontCount; i++) {
531  if (fgFontID[i] == fontid) {
532  fgCurFontIdx = i;
533  return;
534  }
535  }
536 
537  // enough space in cache to load font?
538  if (fgFontCount >= kTTMaxFonts) {
539  Error("TTF::SetTextFont", "too many fonts opened (increase kTTMaxFont = %d)",
540  kTTMaxFonts);
541  Warning("TTF::SetTextFont", "using default font");
542  fgCurFontIdx = 0; // use font 0 (default font, set in ctor)
543  return;
544  }
545 
546  char *ttfont = NULL;
547  int ttindex = 0;
548 
549  FcPattern *pat, *match;
550  FcCharSet *set = NULL;
551  FcResult result;
552 
553  pat = FcPatternCreate ();
554 
555  switch (fontid) {
556  case 1:
557  FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"freeserif");
558  FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_REGULAR);
559  FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ITALIC);
560  break;
561  case 2:
562  FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"freeserif");
563  FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_BOLD);
564  FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ROMAN);
565  break;
566  case 3:
567  FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"freeserif");
568  FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_BOLD);
569  FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ITALIC);
570  break;
571  case 4:
572  FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"freesans");
573  FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_REGULAR);
574  FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ROMAN);
575  break;
576  case 5:
577  FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"freesans");
578  FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_REGULAR);
579  FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ITALIC);
580  break;
581  case 6:
582  FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"freesans");
583  FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_BOLD);
584  FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ROMAN);
585  break;
586  case 7:
587  FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"freesans");
588  FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_BOLD);
589  FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ITALIC);
590  break;
591  case 8:
592  FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"freemono");
593  FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_REGULAR);
594  FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ROMAN);
595  break;
596  case 9:
597  FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"freemono");
598  FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_REGULAR);
599  FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ITALIC);
600  break;
601  case 10:
602  FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"freemono");
603  FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_BOLD);
604  FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ROMAN);
605  break;
606  case 11:
607  FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"freemono");
608  FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_BOLD);
609  FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ITALIC);
610  break;
611  case 12:
612  case 15:
613  FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"symbol");
614  FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_REGULAR);
615  FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ROMAN);
616  break;
617  case 13:
618  FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"freeserif");
619  FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_REGULAR);
620  FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ROMAN);
621  break;
622  case 14:
623  FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"dingbats");
624  FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_REGULAR);
625  FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ROMAN);
626  break;
627  case 16:
628  FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"stixgeneral");
629  FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_REGULAR);
630  FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ROMAN);
631  break;
632  case 17:
633  FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"stixgeneral");
634  FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_REGULAR);
635  FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ITALIC);
636  break;
637  case 18:
638  FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"stixgeneral");
639  FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_BOLD);
640  FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ROMAN);
641  break;
642  case 19:
643  FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"stixgeneral");
644  FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_BOLD);
645  FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ITALIC);
646  break;
647  case 20:
648  FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"stixsize1");
649  FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_REGULAR);
650  FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ROMAN);
651  break;
652  case 21:
653  FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"stixsize1");
654  FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_BOLD);
655  FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ROMAN);
656  break;
657  case 22:
658  FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"stixsize2");
659  FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_REGULAR);
660  FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ROMAN);
661  break;
662  case 23:
663  FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"stixsize2");
664  FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_BOLD);
665  FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ROMAN);
666  break;
667  case 24:
668  FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"stixsize3");
669  FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_REGULAR);
670  FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ROMAN);
671  break;
672  case 25:
673  FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"stixsize3");
674  FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_BOLD);
675  FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ROMAN);
676  break;
677  case 26:
678  FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"stixsize4");
679  FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_REGULAR);
680  FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ROMAN);
681  break;
682  case 27:
683  FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"stixsize4");
684  FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_BOLD);
685  FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ROMAN);
686  break;
687  case 28:
688  FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"stixsize5");
689  FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_REGULAR);
690  FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ROMAN);
691  break;
692  case 29:
693  case 30:
694  case 31:
695  FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"droidsansfallback");
696  FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_REGULAR);
697  FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ROMAN);
698  set = FcCharSetCreate ();
699  FcCharSetAddChar (set, 0x0410); // Cyrillic
700  FcCharSetAddChar (set, 0x4e00); // CJK
701  FcPatternAddCharSet (pat, FC_CHARSET, set);
702  break;
703  default:
704  Error("TTF::SetTextFont", "font %i not known to ROOT", fontid);
705  FcPatternDestroy (pat);
706  Warning("TTF::SetTextFont", "using default font");
707  fgCurFontIdx = 0; // use font 0 (default font, set in ctor)
708  return;
709  break;
710  }
711 
712  FcConfigSubstitute (NULL, pat, FcMatchPattern);
713  FcDefaultSubstitute (pat);
714  match = FcFontMatch (NULL, pat, &result);
715  char *ttfnt;
716  FcPatternGetString (match, FC_FILE, 0, (FcChar8**)&ttfnt);
717  ttfont = StrDup (ttfnt);
718  FcPatternGetInteger (match, FC_INDEX, 0, &ttindex);
719  FcPatternDestroy (match);
720  FcPatternDestroy (pat);
721  if (set) FcCharSetDestroy (set);
722 
723  FT_Face tface = 0;
724 
725  if (FT_New_Face(fgLibrary, ttfont, ttindex, &tface)) {
726  Error("TTF::SetTextFont", "error loading font %s", ttfont);
727  delete [] ttfont;
728  if (tface) FT_Done_Face(tface);
729  Warning("TTF::SetTextFont", "using default font");
730  fgCurFontIdx = 0;
731  return;
732  }
733 
734  delete [] ttfont;
735 
736  fgFontID[fgFontCount] = fontid;
738  fgFace[fgCurFontIdx] = tface;
739  fgCharMap[fgCurFontIdx] = 0;
740  fgFontCount++;
741 
742  if (italic) {
743  FT_Matrix slantMat;
744  slantMat.xx = (1 << 16);
745  slantMat.xy = ((1 << 16) >> 2);
746  slantMat.yx = 0;
747  slantMat.yy = (1 << 16);
748  FT_Set_Transform( fgFace[fgCurFontIdx], &slantMat, NULL );
749  }
750 }
751 
752 ////////////////////////////////////////////////////////////////////////////////
753 /// Set current text size.
754 
755 void TTF::SetTextSize(Float_t textsize)
756 {
757  if (!fgInit) Init();
758  if (textsize < 0) return;
759 
760  if (fgCurFontIdx < 0 || fgFontCount <= fgCurFontIdx) {
761  Error("TTF::SetTextSize", "current font index out of bounds");
762  fgCurFontIdx = 0;
763  return;
764  }
765 
766  Int_t tsize = (Int_t)(textsize*kScale+0.5) << 6;
767  if (FT_Set_Char_Size(fgFace[fgCurFontIdx], tsize, tsize, 72, 72))
768  Error("TTF::SetTextSize", "error in FT_Set_Char_Size");
769 }
770 
771 ////////////////////////////////////////////////////////////////////////////////
772 
773 void TTF::Version(Int_t &major, Int_t &minor, Int_t &patch)
774 {
775  FT_Library_Version(fgLibrary, &major, &minor, &patch);
776 }
777 
778 ////////////////////////////////////////////////////////////////////////////////
779 
781 {
782  return fgHinting;
783 }
784 
785 ////////////////////////////////////////////////////////////////////////////////
786 
788 {
789  return fgKerning;
790 }
791 
792 ////////////////////////////////////////////////////////////////////////////////
793 
795 {
796  return fgSmoothing;
797 }
798 
799 ////////////////////////////////////////////////////////////////////////////////
800 
802 {
803  return fgInit;
804 }
805 
806 ////////////////////////////////////////////////////////////////////////////////
807 
809 {
810  return fgWidth;
811 }
812 
813 ////////////////////////////////////////////////////////////////////////////////
814 
816 {
817  return fgAscent;
818 }
819 
820 ////////////////////////////////////////////////////////////////////////////////
821 
823 {
824  return fgNumGlyphs;
825 }
826 
827 ////////////////////////////////////////////////////////////////////////////////
828 
829 FT_Matrix *TTF::GetRotMatrix()
830 {
831  return fgRotMatrix;
832 }
833 
834 ////////////////////////////////////////////////////////////////////////////////
835 
836 const FT_BBox &TTF::GetBox()
837 {
838  return fgCBox;
839 }
840 
841 ////////////////////////////////////////////////////////////////////////////////
842 
844 {
845  return fgGlyphs;
846 }
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition: TSystem.cxx:931
static void Init()
Initialise the TrueType fonts interface.
Definition: TTF.cxx:66
static const TString & GetTTFFontDir()
Get the fonts directory in the installation. Static utility function.
Definition: TROOT.cxx:2928
FT_Vector fPos
position of glyph origin
Definition: TTF.h:68
static FT_Matrix * fgRotMatrix
rotation matrix
Definition: TTF.h:88
float Float_t
Definition: RtypesCore.h:53
static Int_t fgFontCount
number of fonts loaded
Definition: TTF.h:79
static Bool_t IsInitialized()
Definition: TTF.cxx:801
FT_Glyph fImage
glyph image
Definition: TTF.h:69
unsigned short UShort_t
Definition: RtypesCore.h:36
TH1 * h
Definition: legend2.C:5
static void Cleanup()
Cleanup. Is called by the gCleanupTTF destructor.
Definition: TTF.cxx:88
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
Interface to the freetype 2 library.
Definition: TTF.h:53
TArc * a
Definition: textangle.C:12
#define NULL
Definition: RtypesCore.h:88
static void Version(Int_t &major, Int_t &minor, Int_t &patch)
Definition: TTF.cxx:773
UInt_t fIndex
glyph index in face
Definition: TTF.h:67
short Font_t
Definition: RtypesCore.h:75
static FT_CharMap fgCharMap[kTTMaxFonts]
font character map
Definition: TTF.h:77
double cos(double)
static Int_t fgAscent
string ascent, used to compute Y alignment
Definition: TTF.h:75
static TTF::TTGlyph fgGlyphs[kMaxGlyphs]
glyphs
Definition: TTF.h:82
static void LayoutGlyphs()
Compute the glyphs positions, fgAscent and fgWidth (needed for alignment).
Definition: TTF.cxx:193
static Bool_t GetHinting()
Definition: TTF.cxx:780
static void SetTextFont(Font_t fontnumber)
Definition: TTF.cxx:513
static void GetTextExtent(UInt_t &w, UInt_t &h, char *text)
Get width (w) and height (h) when text is horizontal.
Definition: TTF.cxx:144
static void PrepareString(const char *string)
Put the characters in &quot;string&quot; in the &quot;glyphs&quot; array.
Definition: TTF.cxx:259
static FT_BBox fgCBox
string control box
Definition: TTF.h:76
static void GetTextAdvance(UInt_t &a, char *text)
Get advance (a) when text is horizontal.
Definition: TTF.cxx:160
static TTGlyph * GetGlyphs()
Definition: TTF.cxx:843
constexpr Double_t Pi()
Definition: TMath.h:40
double sin(double)
const Float_t kScale
Definition: TASImage.cxx:130
void Error(const char *location, const char *msgfmt,...)
static Int_t fgTBlankW
trailing blanks width
Definition: TTF.h:90
static void SetSmoothing(Bool_t state)
Set smoothing (anti-aliasing) flag.
Definition: TTF.cxx:374
static Int_t fgCurFontIdx
current font index
Definition: TTF.h:78
static Int_t GetWidth()
Definition: TTF.cxx:808
static FT_Library fgLibrary
FreeType font library.
Definition: TTF.h:86
R__EXTERN TSystem * gSystem
Definition: TSystem.h:539
virtual Int_t GetValue(const char *name, Int_t dflt)
Returns the integer value for a resource.
Definition: TEnv.cxx:482
static Bool_t GetKerning()
Definition: TTF.cxx:787
static Int_t fgFontID[kTTMaxFonts]
font ID
Definition: TTF.h:80
static Bool_t fgKerning
use kerning (true by default)
Definition: TTF.h:85
static Bool_t fgInit
true if the Init has been called
Definition: TTF.h:84
static FT_Matrix * GetRotMatrix()
Definition: TTF.cxx:829
unsigned int UInt_t
Definition: RtypesCore.h:42
TTF helper class containing glyphs description.
Definition: TTF.h:65
short Short_t
Definition: RtypesCore.h:35
static void SetHinting(Bool_t state)
Set hinting flag.
Definition: TTF.cxx:335
void Warning(const char *location, const char *msgfmt,...)
static void SetKerning(Bool_t state)
Set kerning flag.
Definition: TTF.cxx:343
Double_t Cos(Double_t)
Definition: TMath.h:551
char * StrDup(const char *str)
Duplicate the string str.
Definition: TString.cxx:2524
const Bool_t kFALSE
Definition: RtypesCore.h:92
static Bool_t fgHinting
use hinting (true by default)
Definition: TTF.h:83
#define ClassImp(name)
Definition: Rtypes.h:336
static Int_t GetAscent()
Definition: TTF.cxx:815
TText * text
R__EXTERN TEnv * gEnv
Definition: TEnv.h:170
TTF gCleanupTTF
Definition: TTF.cxx:33
static Bool_t fgSmoothing
use anti-aliasing (true when &gt;8 planes, false otherwise)
Definition: TTF.h:89
static void SetRotationMatrix(Float_t angle)
Set the rotation matrix used to rotate the font outlines.
Definition: TTF.cxx:351
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:200
Double_t Sin(Double_t)
Definition: TMath.h:548
static FT_Face fgFace[kTTMaxFonts]
font face
Definition: TTF.h:81
static Int_t fgNumGlyphs
number of glyphs in the string
Definition: TTF.h:87
static void SetTextSize(Float_t textsize)
Set current text size.
Definition: TTF.cxx:755
double result[121]
static Short_t CharToUnicode(UInt_t code)
Map char to unicode. Returns 0 in case no mapping exists.
Definition: TTF.cxx:104
static Int_t GetNumGlyphs()
Definition: TTF.cxx:822
const Bool_t kTRUE
Definition: RtypesCore.h:91
const Int_t n
Definition: legend1.C:16
static Int_t fgWidth
string width, used to compute X alignment
Definition: TTF.h:91
static const FT_BBox & GetBox()
Definition: TTF.cxx:836
static Bool_t GetSmoothing()
Definition: TTF.cxx:794