14 #include <fontconfig/fontconfig.h>
19 #include FT_FREETYPE_H
30 #define KERNING_UNKNOWN (-10000)
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);
111 cGlyph*
Glyph(uint CharCode,
bool AntiAliased =
false)
const;
113 cFreetypeFont(
const char *Name,
int CharHeight,
int CharWidth = 0);
117 virtual int Width(uint c)
const;
118 virtual int Width(
const char *s)
const;
130 int error = FT_Init_FreeType(&
library);
134 if (
face->num_fixed_sizes &&
face->available_sizes) {
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);
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);
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)
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 '?'
267 #define MAX_BLEND_LEVELS 256
279 if (AntiAliased && !TransparentBackground)
280 memset(BlendLevelIndex, 0xFF,
sizeof(BlendLevelIndex));
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));
302 int px = x + pitch + g->
Left() + kerning;
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++) {
327 if (x > Bitmap->
Width() - 1)
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++) {
386 virtual int Width(uint c)
const {
return 10; }
387 virtual int Width(
const char *s)
const {
return 50; }
388 virtual int Height(
void)
const {
return 20; }
417 default:
esyslog(
"ERROR: unknown Font %d (%s %d)", Font, __FUNCTION__, __LINE__);
433 if (!FontNames->
Size()) {
435 FcObjectSet *os = FcObjectSetBuild(FC_FAMILY, FC_STYLE, NULL);
436 FcPattern *pat = FcPatternCreate();
437 FcPatternAddBool(pat, FC_SCALABLE, FcTrue);
439 FcPatternAddInteger(pat, FC_SPACING, FC_MONO);
440 FcFontSet* fontset = FcFontList(NULL, pat, os);
441 for (
int i = 0; i < fontset->nfont; i++) {
442 char *s = (
char *)FcNameUnparse(fontset->fonts[i]);
445 char *c = strchr(s,
':');
447 char *p = strchr(c + 1,
',');
451 char *p = strchr(s,
',');
454 memmove(p, c, strlen(c) + 1);
464 FcFontSetDestroy(fontset);
465 FcPatternDestroy(pat);
466 FcObjectSetDestroy(os);
470 return FontNames->
Size() > 0;
477 char *fn = strdup(FontName);
481 FcPattern *pat = FcNameParse((FcChar8 *)fn);
482 FcPatternAddBool(pat, FC_SCALABLE, FcTrue);
483 FcConfigSubstitute(NULL, pat, FcMatchPattern);
484 FcDefaultSubstitute(pat);
486 FcFontSet *fontset = FcFontSort(NULL, pat, FcFalse, NULL, &fresult);
488 for (
int i = 0; i < fontset->nfont; i++) {
490 FcPatternGetBool(fontset->fonts[i], FC_SCALABLE, 0, &scalable);
493 FcPatternGetString(fontset->fonts[i], FC_FILE, 0, &s);
494 FontFileName = (
char *)s;
498 FcFontSetDestroy(fontset);
501 esyslog(
"ERROR: no usable font found for '%s'", FontName);
502 FcPatternDestroy(pat);
510 cString cFont::Bidi(
const char *Ltr)
513 fribidi_set_mirroring(
true);
514 fribidi_set_reorder_nsm(
false);
515 FriBidiCharSet fribidiCharset = FRIBIDI_CHAR_SET_UTF8;
516 int LtrLen = strlen(Ltr);
517 FriBidiCharType Base = FRIBIDI_TYPE_L;
518 FriBidiChar *Logical =
MALLOC(FriBidiChar, LtrLen + 1) ;
519 int RtlLen = fribidi_charset_to_unicode(fribidiCharset, const_cast<char *>(Ltr), LtrLen, Logical);
520 FriBidiChar *Visual =
MALLOC(FriBidiChar, LtrLen + 1) ;
522 bool ok = fribidi_log2vis(Logical, RtlLen, &Base, Visual, NULL, NULL, NULL);
524 fribidi_remove_bidi_marks(Visual, RtlLen, NULL, NULL, NULL);
525 Rtl =
MALLOC(
char, RtlLen * 4 + 1);
526 fribidi_unicode_to_charset(fribidiCharset, Visual, RtlLen, Rtl);
549 Set(Text, Font, Width);
560 text = Text ? strdup(Text) : NULL;
576 for (
char *p =
text; *p; ) {
582 Blank = Delim = NULL;
586 else if (sl == 1 && isspace(sym))
588 int cw = Font->
Width(sym);
589 if (w + cw > Width) {
604 strcpy(s + l + 1, p);
612 if (strchr(
"-.,:;!?_", *p)) {
641 for (
int i = 0; i < Line; i++) {
650 if ((
eol = strchr(s,
'\n')) != NULL)