Skip to content

Commit

Permalink
Fonts: allow providing and using multiple fallback fonts
Browse files Browse the repository at this point in the history
As our use of the fallback font was a recursive calls, we can
provide chained fallback fonts.
As one of the fallback font could be the main font, we need to
use first getFallbackFont() (to get the first fallback font, even
on a font among these fallback fonts), and getNextFallbackFont()
to get the chained fallback font.
Caveat: we might try rendering/drawing with the main font twice
if it is among the fallback fonts (but avoiding that wouldn't
make this change as simple).
  • Loading branch information
poire-z committed Apr 24, 2020
1 parent 07c03b9 commit f397160
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 68 deletions.
1 change: 1 addition & 0 deletions crengine/include/lvdocviewprops.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#define PROP_LOG_AUTOFLUSH "crengine.log.autoflush"
#define PROP_FONT_SIZE "crengine.font.size"
#define PROP_FALLBACK_FONT_FACE "crengine.font.fallback.face"
// multiple fallback font faces allowed, separated by '|' (name kept singular for compatibility)
#define PROP_STATUS_FONT_COLOR "crengine.page.header.font.color"
#define PROP_STATUS_FONT_FACE "crengine.page.header.font.face"
#define PROP_STATUS_FONT_SIZE "crengine.page.header.font.size"
Expand Down
31 changes: 19 additions & 12 deletions crengine/include/lvfntman.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,8 @@ enum kerning_mode_t {
#define LFNT_HINT_BEGINS_PARAGRAPH 0x0004 /// segment is at start of paragraph
#define LFNT_HINT_ENDS_PARAGRAPH 0x0008 /// segment is at end of paragraph

#define LFNT_HINT_IS_FALLBACK_FONT 0x0010 /// set on recursive Harfbuzz rendering/drawing with a fallback font

// These 4 translate from LTEXT_TD_* equivalents (see lvtextfm.h). Keep them in sync.
#define LFNT_DRAW_UNDERLINE 0x0100 /// underlined text
#define LFNT_DRAW_OVERLINE 0x0200 /// overlined text
Expand Down Expand Up @@ -324,7 +326,7 @@ class LVFont : public LVRefCounter
\param glyph is pointer to glyph_info_t struct to place retrieved info
\return true if glyh was found
*/
virtual bool getGlyphInfo( lUInt32 code, glyph_info_t * glyph, lChar16 def_char=0 ) = 0;
virtual bool getGlyphInfo( lUInt32 code, glyph_info_t * glyph, lChar16 def_char=0, bool is_fallback=false ) = 0;

/** \brief measure text
\param text is text string pointer
Expand Down Expand Up @@ -365,7 +367,7 @@ class LVFont : public LVRefCounter
\param code is unicode character
\return glyph pointer if glyph was found, NULL otherwise
*/
virtual LVFontGlyphCacheItem * getGlyph(lUInt32 ch, lChar16 def_char=0) = 0;
virtual LVFontGlyphCacheItem * getGlyph(lUInt32 ch, lChar16 def_char=0, bool is_fallback=false) = 0;

/// returns font baseline offset
virtual int getBaseline() = 0;
Expand Down Expand Up @@ -436,6 +438,11 @@ class LVFont : public LVRefCounter
virtual void setFallbackFont( LVProtectedFastRef<LVFont> font ) { CR_UNUSED(font); }
/// get fallback font for this font
LVFont * getFallbackFont() { return NULL; }

/// set next fallback font for this font (for when used as a fallback font)
virtual void setNextFallbackFont( LVProtectedFastRef<LVFont> font ) { CR_UNUSED(font); }
/// get next fallback font for this font (when already used as a fallback font)
LVFont * getNextFallbackFont() { return NULL; }
};

typedef LVProtectedFastRef<LVFont> LVFontRef;
Expand Down Expand Up @@ -496,14 +503,14 @@ class LVFontManager
/// returns most similar font
virtual LVFontRef GetFont(int size, int weight, bool italic, css_font_family_t family, lString8 typeface,
int features=0, int documentId = -1, bool useBias=false) = 0;
/// set fallback font face (returns true if specified font is found)
virtual bool SetFallbackFontFace( lString8 face ) { CR_UNUSED(face); return false; }
/// get fallback font face (returns empty string if no fallback font is set)
virtual lString8 GetFallbackFontFace() { return lString8::empty_str; }
/// set fallback font faces (separated by '|')
virtual bool SetFallbackFontFaces( lString8 facesString ) { CR_UNUSED(facesString); return false; }
/// get fallback font faces string (returns empty string if no fallback font is set)
virtual lString8 GetFallbackFontFaces() { return lString8::empty_str; }
/// returns fallback font for specified size
virtual LVFontRef GetFallbackFont(int /*size*/) { return LVFontRef(); }
/// returns fallback font for specified size, weight and italic
virtual LVFontRef GetFallbackFont(int size, int weight=400, bool italic=false ) { return LVFontRef(); }
virtual LVFontRef GetFallbackFont(int size, int weight=400, bool italic=false, lString8 forFaceName=lString8::empty_str ) { return LVFontRef(); }
/// registers font by name
virtual bool RegisterFont( lString8 name ) = 0;
/// registers font by name and face
Expand Down Expand Up @@ -592,7 +599,7 @@ class LBitmapFont : public LVBaseFont
lvfont_handle m_font;
public:
LBitmapFont() : m_font(NULL) { }
virtual bool getGlyphInfo( lUInt32 code, LVFont::glyph_info_t * glyph, lChar16 def_char=0 );
virtual bool getGlyphInfo( lUInt32 code, LVFont::glyph_info_t * glyph, lChar16 def_char=0, bool is_fallback=false );
virtual lUInt16 measureText(
const lChar16 * text, int len,
lUInt16 * widths,
Expand All @@ -612,7 +619,7 @@ class LBitmapFont : public LVBaseFont
virtual lUInt32 getTextWidth(
const lChar16 * text, int len, TextLangCfg * lang_cfg=NULL
);
virtual LVFontGlyphCacheItem * getGlyph(lUInt32 ch, lChar16 def_char=0);
virtual LVFontGlyphCacheItem * getGlyph(lUInt32 ch, lChar16 def_char=0, bool is_fallback=false);
/// returns font baseline offset
virtual int getBaseline();
/// returns font height
Expand Down Expand Up @@ -727,7 +734,7 @@ class LVBaseWin32Font : public LVBaseFont
return css_ff_inherit;
}

virtual LVFontGlyphCacheItem * getGlyph(lUInt32 ch, lChar16 def_char=0) {
virtual LVFontGlyphCacheItem * getGlyph(lUInt32 ch, lChar16 def_char=0, bool is_fallback=false) {
return NULL;
}

Expand All @@ -750,7 +757,7 @@ class LVWin32DrawFont : public LVBaseWin32Font
\param glyph is pointer to glyph_info_t struct to place retrieved info
\return true if glyh was found
*/
virtual bool getGlyphInfo( lUInt32 code, glyph_info_t * glyph, lChar16 def_char=0 );
virtual bool getGlyphInfo( lUInt32 code, glyph_info_t * glyph, lChar16 def_char=0, bool is_fallback=false );

/** \brief measure text
\param glyph is pointer to glyph_info_t struct to place retrieved info
Expand Down Expand Up @@ -930,7 +937,7 @@ class LVWin32Font : public LVBaseWin32Font
\param glyph is pointer to glyph_info_t struct to place retrieved info
\return true if glyh was found
*/
virtual bool getGlyphInfo( lUInt32 code, glyph_info_t * glyph, lChar16 def_char=0 );
virtual bool getGlyphInfo( lUInt32 code, glyph_info_t * glyph, lChar16 def_char=0, bool is_fallback=false );

/** \brief measure text
\param glyph is pointer to glyph_info_t struct to place retrieved info
Expand Down
12 changes: 6 additions & 6 deletions crengine/src/lvdocview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6307,12 +6307,12 @@ CRPropRef LVDocView::propsApply(CRPropRef props) {
} else if (name == PROP_FONT_FACE) {
setDefaultFontFace(UnicodeToUtf8(value));
} else if (name == PROP_FALLBACK_FONT_FACE) {
lString8 oldFace = fontMan->GetFallbackFontFace();
if ( UnicodeToUtf8(value)!=oldFace )
fontMan->SetFallbackFontFace(UnicodeToUtf8(value));
value = Utf8ToUnicode(fontMan->GetFallbackFontFace());
if ( UnicodeToUtf8(value) != oldFace ) {
REQUEST_RENDER("propsApply fallback font face")
lString8 oldFaces = fontMan->GetFallbackFontFaces();
if ( UnicodeToUtf8(value)!=oldFaces )
fontMan->SetFallbackFontFaces(UnicodeToUtf8(value));
value = Utf8ToUnicode(fontMan->GetFallbackFontFaces());
if ( UnicodeToUtf8(value) != oldFaces ) {
REQUEST_RENDER("propsApply fallback font faces")
}
} else if (name == PROP_STATUS_FONT_FACE) {
setStatusFontFace(UnicodeToUtf8(value));
Expand Down
Loading

0 comments on commit f397160

Please sign in to comment.