Skip to content

Commit

Permalink
font: support fallback font to display east asia language.
Browse files Browse the repository at this point in the history
if exitst fallback.font, and font code not exits in the current font and
the replacement font, try get glyph from the fallback font.

Signed-off-by: nx111 <NX111.AimH@gmail.com>

(cherry picked from commit 35a740d)
(cherry picked from commit 7e99dca)
  • Loading branch information
nx111 authored and Huevos committed Dec 2, 2021
1 parent 79ddf41 commit 7129ae8
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 9 deletions.
6 changes: 5 additions & 1 deletion data/fonts/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
installdir = $(datadir)/fonts

dist_install_DATA = *.ttf
dist_install_DATA = *.ttf, *.ttc

install-exec-hook:
cd $(DESTDIR)$(datadir)/fonts && \
$(LN_S) wqy-microhei.ttc fallback.font
Binary file added data/fonts/wqy-microhei.ttc
Binary file not shown.
36 changes: 31 additions & 5 deletions lib/gdi/font.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -291,8 +291,11 @@ std::vector<std::string> fontRenderClass::getFontFaces()
void addFont(const char *filename, const char *alias, int scale_factor, int is_replacement, int renderflags)
{
fontRenderClass::getInstance()->AddFont(filename, alias, scale_factor, renderflags);
if (is_replacement)
if (is_replacement == 1)
eTextPara::setReplacementFont(alias);
else if (is_replacement == -1)
eTextPara::setFallbackFont(alias);

}

DEFINE_REF(Font);
Expand Down Expand Up @@ -568,23 +571,26 @@ eTextPara::~eTextPara()

void eTextPara::setFont(const gFont *font)
{
ePtr<Font> fnt, replacement;
ePtr<Font> fnt, replacement, fallback;
fontRenderClass::getInstance()->getFont(fnt, font->family.c_str(), font->pointSize);
if (!fnt)
eWarning("[eTextPara] Font '%s' is missing!", font->family.c_str());
fontRenderClass::getInstance()->getFont(replacement, replacement_facename.c_str(), font->pointSize);
setFont(fnt, replacement);
fontRenderClass::getInstance()->getFont(fallback, fallback_facename.c_str(), font->pointSize);
setFont(fnt, replacement, fallback);
}

std::string eTextPara::replacement_facename;
std::string eTextPara::fallback_facename;
std::set<int> eTextPara::forced_replaces;

void eTextPara::setFont(Font *fnt, Font *replacement)
void eTextPara::setFont(Font *fnt, Font *replacement, Font *fallback)
{
if (!fnt)
return;
current_font=fnt;
replacement_font=replacement;
fallback_font=fallback;
singleLock s(ftlock);

// we ask for replacment_font first becauseof the cache
Expand Down Expand Up @@ -614,6 +620,19 @@ void eTextPara::setFont(Font *fnt, Font *replacement)
return;
}
}
if (fallback_font)
{
if ((FTC_Manager_LookupFace(fontRenderClass::instance->cacheManager,
fallback_font->scaler.face_id,
&fallback_face) < 0) ||
(FTC_Manager_LookupSize(fontRenderClass::instance->cacheManager,
&fallback_font->scaler,
&fallback_font->size) < 0))
{
eDebug("[eTextPara] FTC_Manager_Lookup_Size failed!");
return;
}
}
previous=0;
use_kerning=FT_HAS_KERNING(current_face);
}
Expand Down Expand Up @@ -858,7 +877,14 @@ nprint: isprintable=0;
index=(rflags&RS_DIRECT)? chr : FT_Get_Char_Index(replacement_face, chr);

if (!index)
eDebug("[eTextPara] Unicode U+%4lx not present", chr);
{
if (fallback_face)
index=(rflags&RS_DIRECT)? chr : FT_Get_Char_Index(fallback_face, chr);
if (!index)
eDebug("[eTextPara] unicode U+%4lx not present", chr);
else
appendGlyph(fallback_font, fallback_face, index, flags, rflags, border, i == uc_visual.end() - 1, activate_newcolor, newcolor);
}
else
appendGlyph(replacement_font, replacement_face, index, flags, rflags, border, i == uc_visual.end() - 1, activate_newcolor, newcolor);
} else
Expand Down
10 changes: 7 additions & 3 deletions lib/gdi/font.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,12 @@ class eLCD;
class eTextPara: public iObject
{
DECLARE_REF(eTextPara);
ePtr<Font> current_font, replacement_font;
FT_Face current_face, replacement_face;
ePtr<Font> current_font, replacement_font, fallback_font;
FT_Face current_face, replacement_face, fallback_face;
int use_kerning;
int previous;
static std::string replacement_facename;
static std::string fallback_facename;
static std::set<int> forced_replaces;

eRect area;
Expand All @@ -148,11 +149,12 @@ class eTextPara: public iObject
int appendGlyph(Font *current_font, FT_Face current_face, FT_UInt glyphIndex, int flags, int rflags, int border, bool last,
bool activate_newcolor, unsigned long newcolor);
void newLine(int flags);
void setFont(Font *font, Font *replacement_font);
void setFont(Font *font, Font *replacement_font, Font *fallback_font);
void calc_bbox();
public:
eTextPara(eRect area, ePoint start=ePoint(-1, -1))
: current_font(0), replacement_font(0), current_face(0), replacement_face(0),
fallback_font(0), fallback_face(0),
area(area), cursor(start), maximum(0, 0), left(start.x()), charCount(0), totalheight(0),
bboxValid(0), doTopBottomReordering(false)
{
Expand All @@ -162,6 +164,8 @@ class eTextPara: public iObject
static void setReplacementFont(std::string font) { replacement_facename=font; }
static void forceReplacementGlyph(int unicode) { forced_replaces.insert(unicode); }

static void setFallbackFont(std::string font) { fallback_facename=font; }

void setFont(const gFont *font);
int renderString(const char *string, int flags=0, int border=0);

Expand Down

0 comments on commit 7129ae8

Please sign in to comment.