vdr  2.4.0
font.c
Go to the documentation of this file.
1 /*
2  * font.c: Font handling for the DVB On Screen Display
3  *
4  * See the main source file 'vdr.c' for copyright information and
5  * how to reach the author.
6  *
7  * BiDi support by Osama Alrawab <alrawab@hotmail.com> @2008 Tripoli-Libya.
8  *
9  * $Id: font.c 4.2 2016/12/22 12:31:23 kls Exp $
10  */
11 
12 #include "font.h"
13 #include <ctype.h>
14 #include <fontconfig/fontconfig.h>
15 #ifdef BIDI
16 #include <fribidi.h>
17 #endif
18 #include <ft2build.h>
19 #include FT_FREETYPE_H
20 #include "config.h"
21 #include "osd.h"
22 #include "tools.h"
23 
24 const char *DefaultFontOsd = "Sans Serif:Bold";
25 const char *DefaultFontSml = "Sans Serif";
26 const char *DefaultFontFix = "Courier:Bold";
27 
28 // --- cFreetypeFont ---------------------------------------------------------
29 
30 #define KERNING_UNKNOWN (-10000)
31 
32 struct tKerning {
33  uint prevSym;
34  int kerning;
35  tKerning(uint PrevSym, int Kerning = 0) { prevSym = PrevSym; kerning = Kerning; }
36  };
37 
38 class cGlyph : public cListObject {
39 private:
40  uint charCode;
42  int advanceX;
43  int advanceY;
44  int left;
45  int top;
46  int width;
47  int rows;
48  int pitch;
50 public:
51  cGlyph(uint CharCode, FT_GlyphSlotRec_ *GlyphData);
52  virtual ~cGlyph();
53  uint CharCode(void) const { return charCode; }
54  uchar *Bitmap(void) const { return bitmap; }
55  int AdvanceX(void) const { return advanceX; }
56  int AdvanceY(void) const { return advanceY; }
57  int Left(void) const { return left; }
58  int Top(void) const { return top; }
59  int Width(void) const { return width; }
60  int Rows(void) const { return rows; }
61  int Pitch(void) const { return pitch; }
62  int GetKerningCache(uint PrevSym) const;
63  void SetKerningCache(uint PrevSym, int Kerning);
64  };
65 
66 cGlyph::cGlyph(uint CharCode, FT_GlyphSlotRec_ *GlyphData)
67 {
69  advanceX = GlyphData->advance.x >> 6;
70  advanceY = GlyphData->advance.y >> 6;
71  left = GlyphData->bitmap_left;
72  top = GlyphData->bitmap_top;
73  width = GlyphData->bitmap.width;
74  rows = GlyphData->bitmap.rows;
75  pitch = GlyphData->bitmap.pitch;
77  memcpy(bitmap, GlyphData->bitmap.buffer, rows * pitch);
78 }
79 
81 {
82  free(bitmap);
83 }
84 
85 int cGlyph::GetKerningCache(uint PrevSym) const
86 {
87  for (int i = kerningCache.Size(); --i > 0; ) {
88  if (kerningCache[i].prevSym == PrevSym)
89  return kerningCache[i].kerning;
90  }
91  return KERNING_UNKNOWN;
92 }
93 
94 void cGlyph::SetKerningCache(uint PrevSym, int Kerning)
95 {
96  kerningCache.Append(tKerning(PrevSym, Kerning));
97 }
98 
99 class cFreetypeFont : public cFont {
100 private:
102  int size;
103  int width;
104  int height;
105  int bottom;
106  FT_Library library;
107  FT_Face face;
110  int Bottom(void) const { return bottom; }
111  int Kerning(cGlyph *Glyph, uint PrevSym) const;
112  cGlyph* Glyph(uint CharCode, bool AntiAliased = false) const;
113 public:
114  cFreetypeFont(const char *Name, int CharHeight, int CharWidth = 0);
115  virtual ~cFreetypeFont();
116  virtual const char *FontName(void) const { return fontName; }
117  virtual int Size(void) const { return size; }
118  virtual int Width(void) const { return width; }
119  virtual int Width(uint c) const;
120  virtual int Width(const char *s) const;
121  virtual int Height(void) const { return height; }
122  virtual void DrawText(cBitmap *Bitmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const;
123  virtual void DrawText(cPixmap *Pixmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const;
124  };
125 
126 cFreetypeFont::cFreetypeFont(const char *Name, int CharHeight, int CharWidth)
127 {
128  fontName = Name;
129  size = CharHeight;
130  width = CharWidth;
131  height = 0;
132  bottom = 0;
133  int error = FT_Init_FreeType(&library);
134  if (!error) {
135  error = FT_New_Face(library, Name, 0, &face);
136  if (!error) {
137  if (face->num_fixed_sizes && face->available_sizes) { // fixed font
138  // TODO what exactly does all this mean?
139  height = face->available_sizes->height;
140  for (uint sym ='A'; sym < 'z'; sym++) { // search for descender for fixed font FIXME
141  FT_UInt glyph_index = FT_Get_Char_Index(face, sym);
142  error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
143  if (!error) {
144  error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
145  if (!error) {
146  if (int(face->glyph->bitmap.rows-face->glyph->bitmap_top) > bottom)
147  bottom = face->glyph->bitmap.rows-face->glyph->bitmap_top;
148  }
149  else
150  esyslog("ERROR: FreeType: error %d in FT_Render_Glyph", error);
151  }
152  else
153  esyslog("ERROR: FreeType: error %d in FT_Load_Glyph", error);
154  }
155  }
156  else {
157  error = FT_Set_Char_Size(face, // handle to face object
158  CharWidth * 64, // CharWidth in 1/64th of points
159  CharHeight * 64, // CharHeight in 1/64th of points
160  0, // horizontal device resolution
161  0); // vertical device resolution
162  if (!error) {
163  height = (face->size->metrics.ascender - face->size->metrics.descender + 63) / 64;
164  bottom = abs((face->size->metrics.descender - 63) / 64);
165  }
166  else
167  esyslog("ERROR: FreeType: error %d during FT_Set_Char_Size (font = %s)\n", error, Name);
168  }
169  }
170  else
171  esyslog("ERROR: FreeType: load error %d (font = %s)", error, Name);
172  }
173  else
174  esyslog("ERROR: FreeType: initialization error %d (font = %s)", error, Name);
175 }
176 
178 {
179  FT_Done_Face(face);
180  FT_Done_FreeType(library);
181 }
182 
183 int cFreetypeFont::Kerning(cGlyph *Glyph, uint PrevSym) const
184 {
185  int kerning = 0;
186  if (Glyph && PrevSym) {
187  kerning = Glyph->GetKerningCache(PrevSym);
188  if (kerning == KERNING_UNKNOWN) {
189  FT_Vector delta;
190  FT_UInt glyph_index = FT_Get_Char_Index(face, Glyph->CharCode());
191  FT_UInt glyph_index_prev = FT_Get_Char_Index(face, PrevSym);
192  FT_Get_Kerning(face, glyph_index_prev, glyph_index, FT_KERNING_DEFAULT, &delta);
193  kerning = delta.x / 64;
194  Glyph->SetKerningCache(PrevSym, kerning);
195  }
196  }
197  return kerning;
198 }
199 
200 cGlyph* cFreetypeFont::Glyph(uint CharCode, bool AntiAliased) const
201 {
202  // Non-breaking space:
203  if (CharCode == 0xA0)
204  CharCode = 0x20;
205 
206  // Lookup in cache:
207  cList<cGlyph> *glyphCache = AntiAliased ? &glyphCacheAntiAliased : &glyphCacheMonochrome;
208  for (cGlyph *g = glyphCache->First(); g; g = glyphCache->Next(g)) {
209  if (g->CharCode() == CharCode)
210  return g;
211  }
212 
213  FT_UInt glyph_index = FT_Get_Char_Index(face, CharCode);
214 
215  // Load glyph image into the slot (erase previous one):
216  int error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
217  if (error)
218  esyslog("ERROR: FreeType: error during FT_Load_Glyph");
219  else {
220 #if ((FREETYPE_MAJOR == 2 && FREETYPE_MINOR == 1 && FREETYPE_PATCH >= 7) || (FREETYPE_MAJOR == 2 && FREETYPE_MINOR == 2 && FREETYPE_PATCH <= 1))// TODO workaround for bug? which one?
221  if (AntiAliased || CharCode == 32)
222 #else
223  if (AntiAliased)
224 #endif
225  error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
226  else
227  error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO);
228  if (error)
229  esyslog("ERROR: FreeType: error during FT_Render_Glyph %d, %d\n", CharCode, glyph_index);
230  else { //new bitmap
231  cGlyph *Glyph = new cGlyph(CharCode, face->glyph);
232  glyphCache->Add(Glyph);
233  return Glyph;
234  }
235  }
236 #define UNKNOWN_GLYPH_INDICATOR '?'
237  if (CharCode != UNKNOWN_GLYPH_INDICATOR)
238  return Glyph(UNKNOWN_GLYPH_INDICATOR, AntiAliased);
239  return NULL;
240 }
241 
242 int cFreetypeFont::Width(uint c) const
243 {
244  cGlyph *g = Glyph(c, Setup.AntiAlias);
245  return g ? g->AdvanceX() : 0;
246 }
247 
248 int cFreetypeFont::Width(const char *s) const
249 {
250  int w = 0;
251  if (s) {
252 #ifdef BIDI
253  cString bs = Bidi(s);
254  s = bs;
255 #endif
256  uint prevSym = 0;
257  while (*s) {
258  int sl = Utf8CharLen(s);
259  uint sym = Utf8CharGet(s, sl);
260  s += sl;
261  cGlyph *g = Glyph(sym, Setup.AntiAlias);
262  if (g)
263  w += g->AdvanceX() + Kerning(g, prevSym);
264  prevSym = sym;
265  }
266  }
267  return w;
268 }
269 
270 #define MAX_BLEND_LEVELS 256
271 
272 void cFreetypeFont::DrawText(cBitmap *Bitmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const
273 {
274  if (s && height) { // checking height to make sure we actually have a valid font
275 #ifdef BIDI
276  cString bs = Bidi(s);
277  s = bs;
278 #endif
279  bool AntiAliased = Setup.AntiAlias && Bitmap->Bpp() >= 8;
280  bool TransparentBackground = ColorBg == clrTransparent;
281  int16_t BlendLevelIndex[MAX_BLEND_LEVELS]; // tIndex is 8 bit unsigned, so a negative value can be used to mark unused entries
282  if (AntiAliased && !TransparentBackground)
283  memset(BlendLevelIndex, 0xFF, sizeof(BlendLevelIndex)); // initializes the array with negative values
284  tIndex fg = Bitmap->Index(ColorFg);
285  uint prevSym = 0;
286  while (*s) {
287  int sl = Utf8CharLen(s);
288  uint sym = Utf8CharGet(s, sl);
289  s += sl;
290  cGlyph *g = Glyph(sym, AntiAliased);
291  if (!g)
292  continue;
293  int kerning = Kerning(g, prevSym);
294  prevSym = sym;
295  uchar *buffer = g->Bitmap();
296  int symWidth = g->Width();
297  if (Width && x + symWidth + g->Left() + kerning - 1 > Width)
298  break; // we don't draw partial characters
299  if (x + symWidth + g->Left() + kerning > 0) {
300  for (int row = 0; row < g->Rows(); row++) {
301  for (int pitch = 0; pitch < g->Pitch(); pitch++) {
302  uchar bt = *(buffer + (row * g->Pitch() + pitch));
303  if (AntiAliased) {
304  if (bt > 0x00) {
305  int px = x + pitch + g->Left() + kerning;
306  int py = y + row + (height - Bottom() - g->Top());
307  tColor bg;
308  if (bt == 0xFF)
309  bg = fg;
310  else if (TransparentBackground)
311  bg = Bitmap->Index(Bitmap->Blend(ColorFg, Bitmap->GetColor(px, py), bt));
312  else if (BlendLevelIndex[bt] >= 0)
313  bg = BlendLevelIndex[bt];
314  else
315  bg = BlendLevelIndex[bt] = Bitmap->Index(Bitmap->Blend(ColorFg, ColorBg, bt));
316  Bitmap->SetIndex(px, py, bg);
317  }
318  }
319  else { //monochrome rendering
320  for (int col = 0; col < 8 && col + pitch * 8 <= symWidth; col++) {
321  if (bt & 0x80)
322  Bitmap->SetIndex(x + col + pitch * 8 + g->Left() + kerning, y + row + (height - Bottom() - g->Top()), fg);
323  bt <<= 1;
324  }
325  }
326  }
327  }
328  }
329  x += g->AdvanceX() + kerning;
330  if (x > Bitmap->Width() - 1)
331  break;
332  }
333  }
334 }
335 
336 void cFreetypeFont::DrawText(cPixmap *Pixmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const
337 {
338  if (s && height) { // checking height to make sure we actually have a valid font
339 #ifdef BIDI
340  cString bs = Bidi(s);
341  s = bs;
342 #endif
343  bool AntiAliased = Setup.AntiAlias;
344  uint prevSym = 0;
345  while (*s) {
346  int sl = Utf8CharLen(s);
347  uint sym = Utf8CharGet(s, sl);
348  s += sl;
349  cGlyph *g = Glyph(sym, AntiAliased);
350  if (!g)
351  continue;
352  int kerning = Kerning(g, prevSym);
353  prevSym = sym;
354  uchar *buffer = g->Bitmap();
355  int symWidth = g->Width();
356  if (Width && x + symWidth + g->Left() + kerning - 1 > Width)
357  break; // we don't draw partial characters
358  if (x + symWidth + g->Left() + kerning > 0) {
359  for (int row = 0; row < g->Rows(); row++) {
360  for (int pitch = 0; pitch < g->Pitch(); pitch++) {
361  uchar bt = *(buffer + (row * g->Pitch() + pitch));
362  if (AntiAliased) {
363  if (bt > 0x00)
364  Pixmap->DrawPixel(cPoint(x + pitch + g->Left() + kerning, y + row + (height - Bottom() - g->Top())), AlphaBlend(ColorFg, ColorBg, bt));
365  }
366  else { //monochrome rendering
367  for (int col = 0; col < 8 && col + pitch * 8 <= symWidth; col++) {
368  if (bt & 0x80)
369  Pixmap->DrawPixel(cPoint(x + col + pitch * 8 + g->Left() + kerning, y + row + (height - Bottom() - g->Top())), ColorFg);
370  bt <<= 1;
371  }
372  }
373  }
374  }
375  }
376  x += g->AdvanceX() + kerning;
377  if (x > Pixmap->DrawPort().Width() - 1)
378  break;
379  }
380  }
381 }
382 
383 // --- cDummyFont ------------------------------------------------------------
384 
385 // A dummy font, in case there are no fonts installed:
386 
387 class cDummyFont : public cFont {
388 private:
389  int height;
390  int width;
391 public:
392  cDummyFont(int CharHeight, int CharWidth) { height = CharHeight; width = CharWidth; }
393  virtual int Width(void) const { return width ? width : height; }
394  virtual int Width(uint c) const { return width ? width : height; }
395  virtual int Width(const char *s) const { return width ? width : height; }
396  virtual int Height(void) const { return height; }
397  virtual void DrawText(cBitmap *Bitmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const {}
398  virtual void DrawText(cPixmap *Pixmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const {};
399  };
400 
401 // --- cFont -----------------------------------------------------------------
402 
403 cFont *cFont::fonts[eDvbFontSize] = { NULL };
404 
405 void cFont::SetFont(eDvbFont Font, const char *Name, int CharHeight)
406 {
407  delete fonts[Font];
408  fonts[Font] = CreateFont(Name, constrain(CharHeight, MINFONTSIZE, MAXFONTSIZE));
409 }
410 
412 {
413  if (Setup.UseSmallFont == 0 && Font == fontSml)
414  Font = fontOsd;
415  else if (Setup.UseSmallFont == 2)
416  Font = fontSml;
417  if (!fonts[Font]) {
418  switch (Font) {
419  case fontOsd: SetFont(Font, Setup.FontOsd, Setup.FontOsdSize); break;
420  case fontSml: SetFont(Font, Setup.FontSml, min(Setup.FontSmlSize, Setup.FontOsdSize)); break;
421  case fontFix: SetFont(Font, Setup.FontFix, Setup.FontFixSize); break;
422  default: esyslog("ERROR: unknown Font %d (%s %d)", Font, __FUNCTION__, __LINE__);
423  }
424  }
425  return fonts[Font];
426 }
427 
428 cFont *cFont::CreateFont(const char *Name, int CharHeight, int CharWidth)
429 {
430  cString fn = GetFontFileName(Name);
431  cFont *f = *fn ? new cFreetypeFont(fn, CharHeight, CharWidth) : NULL;
432  if (!f || !f->Height())
433  f = new cDummyFont(CharHeight, CharWidth);
434  return f;
435 }
436 
437 bool cFont::GetAvailableFontNames(cStringList *FontNames, bool Monospaced)
438 {
439  if (!FontNames->Size()) {
440  FcInit();
441  FcObjectSet *os = FcObjectSetBuild(FC_FAMILY, FC_STYLE, NULL);
442  FcPattern *pat = FcPatternCreate();
443  FcPatternAddBool(pat, FC_SCALABLE, FcTrue);
444  if (Monospaced)
445  FcPatternAddInteger(pat, FC_SPACING, FC_MONO);
446  FcFontSet* fontset = FcFontList(NULL, pat, os);
447  for (int i = 0; i < fontset->nfont; i++) {
448  char *s = (char *)FcNameUnparse(fontset->fonts[i]);
449  if (s) {
450  // Strip i18n stuff:
451  char *c = strchr(s, ':');
452  if (c) {
453  char *p = strchr(c + 1, ',');
454  if (p)
455  *p = 0;
456  }
457  char *p = strchr(s, ',');
458  if (p) {
459  if (c)
460  memmove(p, c, strlen(c) + 1);
461  else
462  *p = 0;
463  }
464  // Make it user presentable:
465  s = strreplace(s, "\\", ""); // '-' is escaped
466  s = strreplace(s, "style=", "");
467  FontNames->Append(s); // takes ownership of s
468  }
469  }
470  FcFontSetDestroy(fontset);
471  FcPatternDestroy(pat);
472  FcObjectSetDestroy(os);
473  //FcFini(); // older versions of fontconfig are broken - and FcInit() can be called more than once
474  FontNames->Sort();
475  }
476  return FontNames->Size() > 0;
477 }
478 
479 cString cFont::GetFontFileName(const char *FontName)
480 {
481  cString FontFileName;
482  if (FontName) {
483  char *fn = strdup(FontName);
484  fn = strreplace(fn, ":", ":style=");
485  fn = strreplace(fn, "-", "\\-");
486  FcInit();
487  FcPattern *pat = FcNameParse((FcChar8 *)fn);
488  FcPatternAddBool(pat, FC_SCALABLE, FcTrue);
489  FcConfigSubstitute(NULL, pat, FcMatchPattern);
490  FcDefaultSubstitute(pat);
491  FcResult fresult;
492  FcFontSet *fontset = FcFontSort(NULL, pat, FcFalse, NULL, &fresult);
493  if (fontset) {
494  for (int i = 0; i < fontset->nfont; i++) {
495  FcBool scalable;
496  FcPatternGetBool(fontset->fonts[i], FC_SCALABLE, 0, &scalable);
497  if (scalable) {
498  FcChar8 *s = NULL;
499  FcPatternGetString(fontset->fonts[i], FC_FILE, 0, &s);
500  FontFileName = (char *)s;
501  break;
502  }
503  }
504  FcFontSetDestroy(fontset);
505  }
506  else
507  esyslog("ERROR: no usable font found for '%s'", FontName);
508  FcPatternDestroy(pat);
509  free(fn);
510  //FcFini(); // older versions of fontconfig are broken - and FcInit() can be called more than once
511  }
512  return FontFileName;
513 }
514 
515 #ifdef BIDI
516 cString cFont::Bidi(const char *Ltr)
517 {
518  if (!cCharSetConv::SystemCharacterTable()) { // bidi requires UTF-8
519  fribidi_set_mirroring(true);
520  fribidi_set_reorder_nsm(false);
521  FriBidiCharSet fribidiCharset = FRIBIDI_CHAR_SET_UTF8;
522  int LtrLen = strlen(Ltr);
523  FriBidiCharType Base = FRIBIDI_TYPE_L;
524  FriBidiChar *Logical = MALLOC(FriBidiChar, LtrLen + 1) ;
525  int RtlLen = fribidi_charset_to_unicode(fribidiCharset, const_cast<char *>(Ltr), LtrLen, Logical);
526  FriBidiChar *Visual = MALLOC(FriBidiChar, LtrLen + 1) ;
527  char *Rtl = NULL;
528  bool ok = fribidi_log2vis(Logical, RtlLen, &Base, Visual, NULL, NULL, NULL);
529  if (ok) {
530  fribidi_remove_bidi_marks(Visual, RtlLen, NULL, NULL, NULL);
531  Rtl = MALLOC(char, RtlLen * 4 + 1);
532  fribidi_unicode_to_charset(fribidiCharset, Visual, RtlLen, Rtl);
533  }
534  free(Logical);
535  free(Visual);
536  if (ok)
537  return cString(Rtl, true);
538  }
539  return cString(Ltr);
540 }
541 #endif
542 
543 // --- cTextWrapper ----------------------------------------------------------
544 
546 {
547  text = eol = NULL;
548  lines = 0;
549  lastLine = -1;
550 }
551 
552 cTextWrapper::cTextWrapper(const char *Text, const cFont *Font, int Width)
553 {
554  text = NULL;
555  Set(Text, Font, Width);
556 }
557 
559 {
560  free(text);
561 }
562 
563 void cTextWrapper::Set(const char *Text, const cFont *Font, int Width)
564 {
565  free(text);
566  text = Text ? strdup(Text) : NULL;
567  eol = NULL;
568  lines = 0;
569  lastLine = -1;
570  if (!text)
571  return;
572  lines = 1;
573  if (Width <= 0)
574  return;
575 
576  char *Blank = NULL;
577  char *Delim = NULL;
578  int w = 0;
579 
580  stripspace(text); // strips trailing newlines
581 
582  for (char *p = text; *p; ) {
583  int sl = Utf8CharLen(p);
584  uint sym = Utf8CharGet(p, sl);
585  if (sym == '\n') {
586  lines++;
587  w = 0;
588  Blank = Delim = NULL;
589  p++;
590  continue;
591  }
592  else if (sl == 1 && isspace(sym))
593  Blank = p;
594  int cw = Font->Width(sym);
595  if (w + cw > Width) {
596  if (Blank) {
597  *Blank = '\n';
598  p = Blank;
599  continue;
600  }
601  else if (w > 0) { // there has to be at least one character before the newline
602  // Here's the ugly part, where we don't have any whitespace to
603  // punch in a newline, so we need to make room for it:
604  if (Delim)
605  p = Delim + 1; // let's fall back to the most recent delimiter
606  char *s = MALLOC(char, strlen(text) + 2); // The additional '\n' plus the terminating '\0'
607  int l = p - text;
608  strncpy(s, text, l);
609  s[l] = '\n';
610  strcpy(s + l + 1, p);
611  free(text);
612  text = s;
613  p = text + l;
614  continue;
615  }
616  }
617  w += cw;
618  if (strchr("-.,:;!?_", *p)) {
619  Delim = p;
620  Blank = NULL;
621  }
622  p += sl;
623  }
624 }
625 
626 const char *cTextWrapper::Text(void)
627 {
628  if (eol) {
629  *eol = '\n';
630  eol = NULL;
631  }
632  return text;
633 }
634 
635 const char *cTextWrapper::GetLine(int Line)
636 {
637  char *s = NULL;
638  if (Line < lines) {
639  if (eol) {
640  *eol = '\n';
641  if (Line == lastLine + 1)
642  s = eol + 1;
643  eol = NULL;
644  }
645  if (!s) {
646  s = text;
647  for (int i = 0; i < Line; i++) {
648  s = strchr(s, '\n');
649  if (s)
650  s++;
651  else
652  break;
653  }
654  }
655  if (s) {
656  if ((eol = strchr(s, '\n')) != NULL)
657  *eol = 0;
658  }
659  lastLine = Line;
660  }
661  return s;
662 }
cTextWrapper(void)
Definition: font.c:545
int AntiAlias
Definition: config.h:327
unsigned char uchar
Definition: tools.h:31
char * text
Definition: font.h:106
cList< cGlyph > glyphCacheAntiAliased
Definition: font.c:109
Definition: osd.h:454
virtual void DrawPixel(const cPoint &Point, tColor Color)=0
Sets the pixel at the given Point to the given Color, which is a full 32 bit ARGB value...
virtual int Height(void) const
Returns the height of this font in pixel (all characters have the same height).
Definition: font.c:396
int top
The bitmap&#39;s top bearing expressed in integer pixels.
Definition: font.c:45
int GetKerningCache(uint PrevSym) const
Definition: font.c:85
Definition: font.h:23
uchar * Bitmap(void) const
Definition: font.c:54
int width
Definition: font.c:390
void Add(cListObject *Object, cListObject *After=NULL)
Definition: tools.c:2152
char * stripspace(char *s)
Definition: tools.c:201
int lines
Definition: font.h:108
const char * Text(void)
Returns the full wrapped text.
Definition: font.c:626
static const char * SystemCharacterTable(void)
Definition: tools.h:172
static void SetFont(eDvbFont Font, const char *Name, int CharHeight)
&lt; Draws the given text into the Pixmap at position (x, y) with the given colors.
Definition: font.c:405
cString fontName
Definition: font.c:101
const cRect & DrawPort(void) const
Returns the pixmap&#39;s draw port, which is relative to the view port.
Definition: osd.h:543
int Index(tColor Color)
Returns the index of the given Color (the first color has index 0).
Definition: osd.c:144
virtual void Append(T Data)
Definition: tools.h:737
virtual ~cGlyph()
Definition: font.c:80
const char * DefaultFontSml
Definition: font.c:25
int Width(void) const
Definition: osd.h:367
#define esyslog(a...)
Definition: tools.h:35
int FontFixSize
Definition: config.h:336
int Left(void) const
Definition: font.c:57
uint CharCode(void) const
Definition: font.c:53
uint prevSym
Definition: font.c:33
int Bottom(void) const
Definition: font.c:110
int advanceY
Definition: font.c:43
char FontSml[MAXFONTNAME]
Definition: config.h:329
Definition: osd.h:306
int rows
The number of bitmap rows.
Definition: font.c:47
int size
Definition: font.c:102
tColor Blend(tColor ColorFg, tColor ColorBg, uint8_t Level) const
Determines a color that consists of a linear blend between ColorFg and ColorBg.
Definition: osd.c:216
static cFont * fonts[]
Definition: font.h:39
T min(T a, T b)
Definition: tools.h:59
int AdvanceY(void) const
Definition: font.c:56
int Top(void) const
Definition: font.c:58
int Bpp(void) const
Definition: osd.h:111
#define MALLOC(type, size)
Definition: tools.h:47
Definition: osd.h:169
int Width(void) const
Definition: osd.h:188
virtual void DrawText(cBitmap *Bitmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const
Draws the given text into the Bitmap at position (x, y) with the given colors.
Definition: font.c:272
#define UNKNOWN_GLYPH_INDICATOR
FT_Library library
Handle to library.
Definition: font.c:106
int pitch
The pitch&#39;s absolute value is the number of bytes taken by one bitmap row, including padding...
Definition: font.c:48
virtual int Height(void) const =0
Returns the height of this font in pixel (all characters have the same height).
int Rows(void) const
Definition: font.c:60
eDvbFont
Definition: font.h:21
Definition: font.h:22
T constrain(T v, T l, T h)
Definition: tools.h:68
void Set(const char *Text, const cFont *Font, int Width)
Wraps the Text to make it fit into the area defined by the given Width when displayed with the given ...
Definition: font.c:563
void SetKerningCache(uint PrevSym, int Kerning)
Definition: font.c:94
virtual int Width(void) const
Returns the original character width as requested when the font was created, or 0 if the default widt...
Definition: font.c:393
FT_Face face
Handle to face object.
Definition: font.c:107
char FontOsd[MAXFONTNAME]
Definition: config.h:328
char * eol
Definition: font.h:107
~cTextWrapper()
Definition: font.c:558
tColor AlphaBlend(tColor ColorFg, tColor ColorBg, uint8_t AlphaLayer)
Definition: osd.c:81
#define KERNING_UNKNOWN
Definition: font.c:30
static const cCursesFont Font
Definition: skincurses.c:32
cSetup Setup
Definition: config.c:372
#define MINFONTSIZE
Definition: font.h:18
cGlyph(uint CharCode, FT_GlyphSlotRec_ *GlyphData)
Definition: font.c:66
static int Utf8CharLen(const char *s)
Definition: si.c:417
const T * Next(const T *Object) const
&lt; Returns the element immediately before Object in this list, or NULL if Object is the first element ...
Definition: tools.h:613
int lastLine
Definition: font.h:109
#define MAXFONTSIZE
Definition: font.h:19
static cFont * CreateFont(const char *Name, int CharHeight, int CharWidth=0)
Creates a new font object with the given Name and makes its characters CharHeight pixels high...
Definition: font.c:428
int Size(void) const
Definition: tools.h:717
int advanceX
Definition: font.c:42
int AdvanceX(void) const
Definition: font.c:55
#define MAX_BLEND_LEVELS
Definition: font.c:270
cVector< tKerning > kerningCache
Definition: font.c:49
const char * DefaultFontFix
Definition: font.c:26
const char * GetLine(int Line)
Returns the given Line. The first line is numbered 0.
Definition: font.c:635
int bottom
Definition: font.c:105
uchar * bitmap
Definition: font.c:41
virtual int Width(void) const =0
Returns the original character width as requested when the font was created, or 0 if the default widt...
int Width(void) const
Definition: font.c:59
cGlyph * Glyph(uint CharCode, bool AntiAliased=false) const
Definition: font.c:200
char FontFix[MAXFONTNAME]
Definition: config.h:330
int kerning
Definition: font.c:34
static cString GetFontFileName(const char *FontName)
Returns the actual font file name for the given FontName.
Definition: font.c:479
virtual int Width(const char *s) const
Returns the width of the given string in pixel.
Definition: font.c:395
virtual int Width(void) const
Returns the original character width as requested when the font was created, or 0 if the default widt...
Definition: font.c:118
int height
Definition: font.c:104
static bool GetAvailableFontNames(cStringList *FontNames, bool Monospaced=false)
Queries the font configuration for a list of available font names, which is returned in FontNames...
Definition: font.c:437
virtual void DrawText(cPixmap *Pixmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const
Definition: font.c:398
int width
The number of pixels per bitmap row.
Definition: font.c:46
uint Utf8CharGet(const char *s, int Length)
Returns the UTF-8 symbol at the beginning of the given string.
Definition: tools.c:807
virtual int Height(void) const
Returns the height of this font in pixel (all characters have the same height).
Definition: font.c:121
int width
Definition: font.c:103
cFreetypeFont(const char *Name, int CharHeight, int CharWidth=0)
Definition: font.c:126
int FontOsdSize
Definition: config.h:334
int UseSmallFont
Definition: config.h:326
Definition: font.c:38
virtual void DrawText(cBitmap *Bitmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const
Draws the given text into the Bitmap at position (x, y) with the given colors.
Definition: font.c:397
void Sort(bool IgnoreCase=false)
Definition: tools.h:806
cList< cGlyph > glyphCacheMonochrome
Definition: font.c:108
uint charCode
Definition: font.c:40
tColor GetColor(int x, int y) const
Returns the color at the given coordinates.
Definition: osd.h:277
int height
Definition: font.c:389
int left
The bitmap&#39;s left bearing expressed in integer pixels.
Definition: font.c:44
virtual ~cFreetypeFont()
Definition: font.c:177
int FontSmlSize
Definition: config.h:335
const T * First(void) const
Returns the first element in this list, or NULL if the list is empty.
Definition: tools.h:606
cDummyFont(int CharHeight, int CharWidth)
Definition: font.c:392
uint8_t tIndex
Definition: font.h:31
const char * DefaultFontOsd
Definition: font.c:24
int Kerning(cGlyph *Glyph, uint PrevSym) const
Definition: font.c:183
tKerning(uint PrevSym, int Kerning=0)
Definition: font.c:35
void SetIndex(int x, int y, tIndex Index)
Sets the index at the given coordinates to Index.
Definition: osd.c:500
int Pitch(void) const
Definition: font.c:61
char * strreplace(char *s, char c1, char c2)
Definition: tools.c:139
#define eDvbFontSize
Definition: font.h:25
Definition: font.h:37
virtual const char * FontName(void) const
Returns the font name.
Definition: font.c:116
Definition: tools.h:176
Definition: font.c:32
static const cFont * GetFont(eDvbFont Font)
Gets the given Font, which was previously set by a call to SetFont().
Definition: font.c:411
virtual int Size(void) const
Returns the original size as requested when the font was created.
Definition: font.c:117
uint32_t tColor
Definition: font.h:29
virtual int Width(uint c) const
Returns the width of the given character in pixel.
Definition: font.c:394