14 #include <fontconfig/fontconfig.h> 19 #include FT_FREETYPE_H 30 #define KERNING_UNKNOWN (-10000) 35 tKerning(uint PrevSym,
int Kerning = 0) { prevSym = PrevSym; kerning = Kerning; }
51 cGlyph(uint CharCode, FT_GlyphSlotRec_ *GlyphData);
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);
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);
87 for (
int i = kerningCache.Size(); --i > 0; ) {
88 if (kerningCache[i].
prevSym == PrevSym)
89 return kerningCache[i].kerning;
96 kerningCache.Append(
tKerning(PrevSym, Kerning));
109 int Bottom(
void)
const {
return bottom; }
110 int Kerning(
cGlyph *Glyph, uint PrevSym)
const;
111 cGlyph* Glyph(uint CharCode,
bool AntiAliased =
false)
const;
113 cFreetypeFont(
const char *Name,
int CharHeight,
int CharWidth = 0);
115 virtual const char *
FontName(
void)
const {
return fontName; }
116 virtual int Size(
void)
const {
return size; }
117 virtual int Width(uint c)
const;
118 virtual int Width(
const char *s)
const;
119 virtual int Height(
void)
const {
return height; }
120 virtual void DrawText(
cBitmap *Bitmap,
int x,
int y,
const char *s,
tColor ColorFg,
tColor ColorBg,
int Width)
const;
121 virtual void DrawText(
cPixmap *Pixmap,
int x,
int y,
const char *s,
tColor ColorFg,
tColor ColorBg,
int Width)
const;
130 int error = FT_Init_FreeType(&library);
132 error = FT_New_Face(library, Name, 0, &face);
134 if (face->num_fixed_sizes && face->available_sizes) {
136 height = face->available_sizes->height;
137 for (uint sym =
'A'; sym <
'z'; sym++) {
138 FT_UInt glyph_index = FT_Get_Char_Index(face, sym);
139 error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
141 error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
143 if (face->glyph->bitmap.rows-face->glyph->bitmap_top > bottom)
144 bottom = face->glyph->bitmap.rows-face->glyph->bitmap_top;
147 esyslog(
"ERROR: FreeType: error %d in FT_Render_Glyph", error);
150 esyslog(
"ERROR: FreeType: error %d in FT_Load_Glyph", error);
154 error = FT_Set_Char_Size(face,
160 height = (face->size->metrics.ascender - face->size->metrics.descender + 63) / 64;
161 bottom = abs((face->size->metrics.descender - 63) / 64);
164 esyslog(
"ERROR: FreeType: error %d during FT_Set_Char_Size (font = %s)\n", error, Name);
168 esyslog(
"ERROR: FreeType: load error %d (font = %s)", error, Name);
171 esyslog(
"ERROR: FreeType: initialization error %d (font = %s)", error, Name);
177 FT_Done_FreeType(library);
183 if (Glyph && PrevSym) {
187 FT_UInt glyph_index = FT_Get_Char_Index(face, Glyph->
CharCode());
188 FT_UInt glyph_index_prev = FT_Get_Char_Index(face, PrevSym);
189 FT_Get_Kerning(face, glyph_index_prev, glyph_index, FT_KERNING_DEFAULT, &delta);
190 kerning = delta.x / 64;
200 if (CharCode == 0xA0)
204 cList<cGlyph> *glyphCache = AntiAliased ? &glyphCacheAntiAliased : &glyphCacheMonochrome;
206 if (g->CharCode() == CharCode)
210 FT_UInt glyph_index = FT_Get_Char_Index(face, CharCode);
213 int error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
215 esyslog(
"ERROR: FreeType: error during FT_Load_Glyph");
217 #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? 218 if (AntiAliased || CharCode == 32)
222 error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
224 error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO);
226 esyslog(
"ERROR: FreeType: error during FT_Render_Glyph %d, %d\n", CharCode, glyph_index);
229 glyphCache->
Add(Glyph);
233 #define UNKNOWN_GLYPH_INDICATOR '?' 260 w += g->
AdvanceX() + Kerning(g, prevSym);
267 #define MAX_BLEND_LEVELS 256 279 if (AntiAliased && !TransparentBackground)
280 memset(BlendLevelIndex, 0xFF,
sizeof(BlendLevelIndex));
287 cGlyph *g = Glyph(sym, AntiAliased);
290 int kerning = Kerning(g, prevSym);
293 int symWidth = g->
Width();
294 if (Width && x + symWidth + g->
Left() + kerning - 1 > Width)
296 if (x + symWidth + g->
Left() + kerning > 0) {
297 for (
int row = 0; row < g->
Rows(); row++) {
298 for (
int pitch = 0; pitch < g->
Pitch(); pitch++) {
299 uchar bt = *(buffer + (row * g->
Pitch() + pitch));
303 int py = y + row + (height - Bottom() - g->
Top());
307 else if (TransparentBackground)
309 else if (BlendLevelIndex[bt] >= 0)
310 bg = BlendLevelIndex[bt];
312 bg = BlendLevelIndex[bt] = Bitmap->
Index(Bitmap->
Blend(ColorFg, ColorBg, bt));
317 for (
int col = 0; col < 8 && col + pitch * 8 <= symWidth; col++) {
319 Bitmap->
SetIndex(x + col + pitch * 8 + g->
Left() +
kerning, y + row + (height - Bottom() - g->
Top()), fg);
327 if (x > Bitmap->
Width() - 1)
346 cGlyph *g = Glyph(sym, AntiAliased);
349 int kerning = Kerning(g, prevSym);
352 int symWidth = g->
Width();
353 if (Width && x + symWidth + g->
Left() + kerning - 1 > Width)
355 if (x + symWidth + g->
Left() + kerning > 0) {
356 for (
int row = 0; row < g->
Rows(); row++) {
357 for (
int pitch = 0; pitch < g->
Pitch(); pitch++) {
358 uchar bt = *(buffer + (row * g->
Pitch() + pitch));
364 for (
int col = 0; col < 8 && col + pitch * 8 <= symWidth; col++) {
389 virtual int Width(uint c)
const {
return height; }
390 virtual int Width(
const char *s)
const {
return height; }
391 virtual int Height(
void)
const {
return height; }
417 default:
esyslog(
"ERROR: unknown Font %d (%s %d)", Font, __FUNCTION__, __LINE__);
425 cString fn = GetFontFileName(Name);
434 if (!FontNames->
Size()) {
436 FcObjectSet *os = FcObjectSetBuild(FC_FAMILY, FC_STYLE, NULL);
437 FcPattern *pat = FcPatternCreate();
438 FcPatternAddBool(pat, FC_SCALABLE, FcTrue);
440 FcPatternAddInteger(pat, FC_SPACING, FC_MONO);
441 FcFontSet* fontset = FcFontList(NULL, pat, os);
442 for (
int i = 0; i < fontset->nfont; i++) {
443 char *s = (
char *)FcNameUnparse(fontset->fonts[i]);
446 char *c = strchr(s,
':');
448 char *p = strchr(c + 1,
',');
452 char *p = strchr(s,
',');
455 memmove(p, c, strlen(c) + 1);
465 FcFontSetDestroy(fontset);
466 FcPatternDestroy(pat);
467 FcObjectSetDestroy(os);
471 return FontNames->
Size() > 0;
478 char *fn = strdup(FontName);
482 FcPattern *pat = FcNameParse((FcChar8 *)fn);
483 FcPatternAddBool(pat, FC_SCALABLE, FcTrue);
484 FcConfigSubstitute(NULL, pat, FcMatchPattern);
485 FcDefaultSubstitute(pat);
487 FcFontSet *fontset = FcFontSort(NULL, pat, FcFalse, NULL, &fresult);
489 for (
int i = 0; i < fontset->nfont; i++) {
491 FcPatternGetBool(fontset->fonts[i], FC_SCALABLE, 0, &scalable);
494 FcPatternGetString(fontset->fonts[i], FC_FILE, 0, &s);
495 FontFileName = (
char *)s;
499 FcFontSetDestroy(fontset);
502 esyslog(
"ERROR: no usable font found for '%s'", FontName);
503 FcPatternDestroy(pat);
511 cString cFont::Bidi(
const char *Ltr)
514 fribidi_set_mirroring(
true);
515 fribidi_set_reorder_nsm(
false);
516 FriBidiCharSet fribidiCharset = FRIBIDI_CHAR_SET_UTF8;
517 int LtrLen = strlen(Ltr);
518 FriBidiCharType Base = FRIBIDI_TYPE_L;
519 FriBidiChar *Logical =
MALLOC(FriBidiChar, LtrLen + 1) ;
520 int RtlLen = fribidi_charset_to_unicode(fribidiCharset, const_cast<char *>(Ltr), LtrLen, Logical);
521 FriBidiChar *Visual =
MALLOC(FriBidiChar, LtrLen + 1) ;
523 bool ok = fribidi_log2vis(Logical, RtlLen, &Base, Visual, NULL, NULL, NULL);
525 fribidi_remove_bidi_marks(Visual, RtlLen, NULL, NULL, NULL);
526 Rtl =
MALLOC(
char, RtlLen * 4 + 1);
527 fribidi_unicode_to_charset(fribidiCharset, Visual, RtlLen, Rtl);
550 Set(Text, Font, Width);
561 text = Text ? strdup(Text) : NULL;
577 for (
char *p = text; *p; ) {
583 Blank = Delim = NULL;
587 else if (sl == 1 && isspace(sym))
589 int cw = Font->
Width(sym);
590 if (w + cw > Width) {
601 char *s =
MALLOC(
char, strlen(text) + 2);
605 strcpy(s + l + 1, p);
613 if (strchr(
"-.,:;!?_", *p)) {
636 if (Line == lastLine + 1)
642 for (
int i = 0; i < Line; i++) {
651 if ((eol = strchr(s,
'\n')) != NULL)
cList< cGlyph > glyphCacheAntiAliased
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).
int top
The bitmap's top bearing expressed in integer pixels.
int GetKerningCache(uint PrevSym) const
uchar * Bitmap(void) const
void Add(cListObject *Object, cListObject *After=NULL)
const char * Text(void)
Returns the full wrapped text.
static const char * SystemCharacterTable(void)
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.
const cRect & DrawPort(void) const
Returns the pixmap's draw port, which is relative to the view port.
int Index(tColor Color)
Returns the index of the given Color (the first color has index 0).
virtual void Append(T Data)
const char * DefaultFontSml
uint CharCode(void) const
char FontSml[MAXFONTNAME]
int rows
The number of bitmap rows.
tColor Blend(tColor ColorFg, tColor ColorBg, uint8_t Level) const
Determines a color that consists of a linear blend between ColorFg and ColorBg.
virtual int Width(uint c) const
Returns the width of the given character in pixel.
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.
#define UNKNOWN_GLYPH_INDICATOR
FT_Library library
Handle to library.
int pitch
The pitch's absolute value is the number of bytes taken by one bitmap row, including padding...
T * Next(const T *object) const
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 ...
void SetKerningCache(uint PrevSym, int Kerning)
FT_Face face
Handle to face object.
char FontOsd[MAXFONTNAME]
tColor AlphaBlend(tColor ColorFg, tColor ColorBg, uint8_t AlphaLayer)
static const cCursesFont Font
cGlyph(uint CharCode, FT_GlyphSlotRec_ *GlyphData)
static int Utf8CharLen(const char *s)
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...
cVector< tKerning > kerningCache
const char * DefaultFontFix
const char * GetLine(int Line)
Returns the given Line. The first line is numbered 0.
cGlyph * Glyph(uint CharCode, bool AntiAliased=false) const
char FontFix[MAXFONTNAME]
static cString GetFontFileName(const char *FontName)
Returns the actual font file name for the given FontName.
virtual int Width(const char *s) const
Returns the width of the given string in pixel.
virtual int Width(uint c) const =0
Returns the width of the given character in pixel.
static bool GetAvailableFontNames(cStringList *FontNames, bool Monospaced=false)
Queries the font configuration for a list of available font names, which is returned in FontNames...
virtual void DrawText(cPixmap *Pixmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const
int width
The number of pixels per bitmap row.
virtual int Height(void) const
Returns the height of this font in pixel (all characters have the same height).
cFreetypeFont(const char *Name, int CharHeight, int CharWidth=0)
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.
void Sort(bool IgnoreCase=false)
cList< cGlyph > glyphCacheMonochrome
tColor GetColor(int x, int y) const
Returns the color at the given coordinates.
int left
The bitmap's left bearing expressed in integer pixels.
virtual int Height(void) const =0
Returns the height of this font in pixel (all characters have the same height).
const char * DefaultFontOsd
cDummyFont(int CharHeight)
int Kerning(cGlyph *Glyph, uint PrevSym) const
tKerning(uint PrevSym, int Kerning=0)
void SetIndex(int x, int y, tIndex Index)
Sets the index at the given coordinates to Index.
virtual const char * FontName(void) const
Returns the font name.
static const cFont * GetFont(eDvbFont Font)
Gets the given Font, which was previously set by a call to SetFont().
virtual int Size(void) const
Returns the original size as requested when the font was created.
virtual int Width(uint c) const
Returns the width of the given character in pixel.