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